Greedy Algorithm - How to Succeed in Algorithms


Greedy Algorithm - How to Succeed in Algorithms

How to Succeed in Algorithms Interview Series


Applications of Greedy Algorithm

  • Optimize DP or other solution from O(n^2) to O(n)
  • strategy used to pick element

Usually used together with Greedy Algorithm

How

  • Record/Update maxReach

Examples

public String strWithout3a3b(int A, int B) {
  StringBuilder res = new StringBuilder(A + B);
  char a = 'a', b = 'b';
  int i = A, j = B;
  if (B > A) { a = 'b'; b = 'a'; i = B; j = A; }
  while (i-- > 0) {
    res.append(a);
    if (i > j) { res.append(a); --i; }
    if (j-- > 0) res.append(b);
  }
  return res.toString();
}
public int jump(int[] A) {
    int jumps = 0, curEnd = 0, curFarthest = 0;
    for (int i = 0; i < A.length - 1; i++) {
        curFarthest = Math.max(curFarthest, i + A[i]);
        if (i == curEnd) {
            jumps++;
            curEnd = curFarthest;
        }
    }
    return jumps;
}

int jump(int A[], int n) {
    int curMax = 0, steps = 0, i = 0;
    while(curMax<n-1) {
        int lastMax = curMax;
        for(; i<=lastMax; i++)
            curMax = max(curMax,i+A[i]);
        steps++;
        if(lastMax == curMax) return -1;
    }
    return steps;
}
public int findLongestChain(int[][] pairs) {
    Arrays.sort(pairs, (a,b) -> a[1] - b[1]);
    int sum = 0, n = pairs.length, i = -1;
    while (++i < n) {
        sum++;
        int curEnd = pairs[i][1];
        while (i+1 < n && pairs[i+1][0] <= curEnd) i++;
    }
    return sum;
}

Hard

public int minKBitFlips(int[] A, int K) {
    int count = 0;
    for(int i = 0; i < A.length; i++) {
        if(A[i] == 0 && i + K <= A.length) {
            for(int j = 0; j < K; j++) {
                A[i + j] = A[i + j] == 0 ? 1 : 0;
            }
            count++;
        }
        else if(A[i] == 0) {
            return -1;
        }
    }
    return count;
}
//
public int minKBitFlips(int[] A, int K) {
    int totalFlips = 0, currentEffectiveFlips = 0;
    Deque<Integer> flipIndices = new ArrayDeque<>();
    for(int i = 0; i < A.length; i++) {
        if(flipIndices.size() > 0 && flipIndices.peekFirst() + K == i) {
            flipIndices.remove();
            currentEffectiveFlips--;
        }
        if(A[i] == 0 && currentEffectiveFlips % 2 == 0
           || A[i] == 1 && currentEffectiveFlips % 2 != 0) {
            if(i + K > A.length) {
                return -1;
            }
            flipIndices.addLast(i);
            currentEffectiveFlips++;
            totalFlips++;
        }
    }
    return totalFlips;
}

Sort multiple arrays then two pointers

Multiple criteria

  • sort by one, scan them
  • use PQ to store them in another order

Sort + PriorityQueue to get/remove min/max

public int scheduleCourse(int[][] courses) {
    Arrays.sort(courses,(a,b)->a[1]-b[1]); //Sort the courses by their deadlines (Greedy! We have to deal with courses with early deadlines first)
    PriorityQueue<Integer> pq=new PriorityQueue<>((a,b)->b-a);
    int time=0;
    for (int[] c:courses)
    {
        time+=c[0]; // add current course to a priority queue
        pq.add(c[0]);
        if (time>c[1]) time-=pq.poll(); //If time exceeds, drop the previous course which costs the most time. (That must be the best choice!)
    }        
    return pq.size();
}
public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
    int size = Profits.length;
    int ans = W;
    Point projects[] = new Point[size];
    for (int i = 0; i < projects.length; i++) {
        projects[i] = new Point(Capital[i], Profits[i]);
    }
    Arrays.sort(projects, new Comparator<Point>(){
        public int compare(Point a, Point b) {
            if (a.x == b.x)
                return a.y - b.y;
            return a.x - b.x;
        }
    });
    PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Comparator.reverseOrder());
    int j = 0;
    for (int i = 0; i < Math.min(k, size); i++) {
        while(j < size && projects[j].x <= ans) {
            pq.add(projects[j].y);
            j++;
        }
        if (!pq.isEmpty())
            ans += pq.poll();
    }
    return ans;
}

Enumerate + use PQ to get/remove min/max

public double mincostToHireWorkers(int[] quality, int[] wage, int K) {       
    int numWorkers = quality.length;
    /* qualityRatio[i] = {quality, wage[i] / quality[i]}. */
    double[][] qualityRatio = new double[numWorkers][2];
    for (int i = 0; i < numWorkers; i++) {
        qualityRatio[i][0] = quality[i];
        qualityRatio[i][1] = (double) wage[i] / quality[i];
    }
    Arrays.sort(qualityRatio, (a, b) -> Double.compare(a[1], b[1]));
    double minSumSalary = Integer.MAX_VALUE;
    int sumQuality = 0;;
    /* Always remove maximum quality. */
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> Integer.compare(b, a));
    for (int i = 0; i < numWorkers; i++) {
        maxHeap.add((int)qualityRatio[i][0]);
        sumQuality += qualityRatio[i][0];
        if (maxHeap.size() > K) {
            int qualityPolled = maxHeap.poll();
            sumQuality -= qualityPolled;
        }        
        if (maxHeap.size() == K) {
            /* Calculate sumSalary. */
            double curRatio = qualityRatio[i][1];
            minSumSalary = Math.min(minSumSalary, sumQuality * curRatio);
        }
    }    
    return minSumSalary;
}

Proof

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)