Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Greedy Revision
DSA

Greedy Revision

Quickly revise greedy strategies, correctness intuition, and common problem types.

Sort intervals by end time ascending

count = 1
last_end = first_interval.end

For each interval from second onward:
    If interval.start >= last_end:
        count++
        last_end = interval.end

Return count

Input: Array of (start, end) intervals Greedy Rule: Pick interval with earliest finishing time Time: O(n log n)

public int activitySelection(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[1] - b[1]);

    int count = 1;
    int lastEnd = intervals[0][1];

    for (int i = 1; i < intervals.length; i++) {
        if (intervals[i][0] >= lastEnd) {
            count++;
            lastEnd = intervals[i][1];
        }
    }
    return count;
}

2 Minimum Spanning Tree (Prim’s Algorithm)

Initialize visited array
Min-heap (weight, node)

Push (0, source)
total_cost = 0

While heap not empty:
    pop smallest edge
    If node not visited:
        mark visited
        add weight to total_cost

        For each neighbor:
            If not visited:
                push to heap

Input: Weighted adjacency list Time: O((V + E) log V)

class Pair {
    int node, weight;
    Pair(int n, int w) {
        node = n;
        weight = w;
    }
}

public int primMST(int V, List<List<Pair>> graph) {
    boolean[] visited = new boolean[V];
    PriorityQueue<Pair> pq =
        new PriorityQueue<>((a, b) -> a.weight - b.weight);

    pq.offer(new Pair(0, 0));
    int totalCost = 0;

    while (!pq.isEmpty()) {
        Pair current = pq.poll();

        if (visited[current.node]) continue;

        visited[current.node] = true;
        totalCost += current.weight;

        for (Pair neighbor : graph.get(current.node)) {
            if (!visited[neighbor.node]) {
                pq.offer(new Pair(neighbor.node, neighbor.weight));
            }
        }
    }
    return totalCost;
}

3 Coin Change (Greedy – Canonical Systems Only)

Sort coins in descending order

count = 0

For each coin:
    While amount >= coin:
        amount -= coin
        count++

Return count

Works only for canonical denominations (e.g., 1,2,5,10,20…) Fails for arbitrary coin systems.

public int coinChangeGreedy(int[] coins, int amount) {
    Arrays.sort(coins);
    int count = 0;

    for (int i = coins.length - 1; i >= 0; i--) {
        while (amount >= coins[i]) {
            amount -= coins[i];
            count++;
        }
    }
    return amount == 0 ? count : -1;
}

4 Huffman Encoding

Insert all frequencies into min-heap

While heap size > 1:
    left = extract min
    right = extract min
    merged = left + right
    insert merged

Return final node

Input: Array of frequencies Greedy Rule: Merge two smallest weights Time: O(n log n)

public int huffmanCost(int[] freq) {
    PriorityQueue<Integer> pq = new PriorityQueue<>();

    for (int f : freq)
        pq.offer(f);

    int cost = 0;

    while (pq.size() > 1) {
        int left = pq.poll();
        int right = pq.poll();

        int merged = left + right;
        cost += merged;

        pq.offer(merged);
    }
    return cost;
}

5 Geometry / Line / Convex Hull (Cross Product)

Sort points by x (then y)

For each point:
    While last two points + current
          make non-left turn:
        remove last point
    Add current point

Core Tool: Cross product cross(A, B, C) = (B-A) × (C-A)

Used in: Convex Hull (Monotonic Chain)

public int cross(int[] A, int[] B, int[] C) {
    return (B[0] - A[0]) * (C[1] - A[1]) -
           (B[1] - A[1]) * (C[0] - A[0]);
}

6 Fractional Knapsack

For each item:
    compute ratio = value / weight

Sort items by ratio descending

For each item:
    If capacity >= weight:
        take whole item
    Else:
        take fraction
        break

Input: weights[], values[], capacity Time: O(n log n)

class Item {
    int value, weight;
    Item(int v, int w) {
        value = v;
        weight = w;
    }
}

public double fractionalKnapsack(int W, Item[] items) {
    Arrays.sort(items,
        (a, b) -> Double.compare(
            (double)b.value / b.weight,
            (double)a.value / a.weight));

    double totalValue = 0.0;

    for (Item item : items) {
        if (W >= item.weight) {
            totalValue += item.value;
            W -= item.weight;
        } else {
            totalValue +=
                ((double)item.value / item.weight) * W;
            break;
        }
    }
    return totalValue;
}

7 Interval Merging / Skyline

Sort intervals by start

merged = empty list

For interval:
    If merged empty OR
       interval.start > last.end:
        add interval
    Else:
        last.end = max(last.end, interval.end)

Return merged

Input: Array of intervals Time: O(n log n)

public int[][] merge(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);

    List<int[]> merged = new ArrayList<>();

    for (int[] interval : intervals) {
        if (merged.isEmpty() ||
            merged.get(merged.size() - 1)[1] < interval[0]) {
            merged.add(interval);
        } else {
            merged.get(merged.size() - 1)[1] =
                Math.max(merged.get(merged.size() - 1)[1],
                         interval[1]);
        }
    }
    return merged.toArray(new int[merged.size()][]);
}

My Private Notes

Notes are auto-saved locally to this device.