DSA
    intermediate

    Greedy Algorithms

    Greedy Algorithms: Activity Selection

    Learn the greedy paradigm through Activity Selection: always pick the compatible activity that finishes earliest. The exchange argument proves this greedy choice is optimal — and shows when the same intuition silently fails.

    ⏱ O(n log n)
    💾 O(n)
    Ready
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [1,4]
    [3,5]
    [0,5]
    [4,7]
    [6,8]
    [7,10]
    [9,12]
    [11,14]
    CandidateConsideringSelectedRejected

    When greedy fails: 0/1 Knapsack

    Activity selection's greedy rule is safe because an exchange argument proves that swapping any other first choice for the earliest-finishing compatible activity never decreases the total count. In 0/1 Knapsack (maximize value under a weight limit; items are indivisible), greedily taking the best value/weight ratio can commit capacity that a different combination of "worse-ratio" items would use more efficiently — no exchange argument holds, so dynamic programming is required to explore every include/exclude branch.

    Input: 8 activities with [start, end] time slots. Goal: schedule as many non-overlapping activities as possible.

    50%
    Live Variables
    n8
    lastEnd−∞
    phaseinput

    Does greedy work here?

    Sort

    Sort each problem by whether the obvious greedy choice is optimal.

    Tap a piece, then tap where it goes — or drag it. Tap the tray to take one back.

    Greedy is optimal

    Drop items here

    Greedy can fail

    Drop items here
    6 pieces left to place

    Test your knowledge

    20 questions
    Question 1 of 20
    Score: 0

    What is the time complexity of the greedy Activity Selection algorithm?

    Write the code

    Runs your solution

    Activity Selection — Maximum Non-Overlapping Count

    Given a list of activities where each activity is [start, end], return the maximum number of non-overlapping activities that can be selected. Two activities are non-overlapping if one ends before or exactly when the next one starts (end1 <= start2). Example: Input: [[1,4],[3,5],[0,5],[4,7],[6,8],[7,10],[9,12],[11,14]] Output: 4 Explanation: Select [1,4],[4,7],[7,10],[11,14] — no two overlap.

    Example Cases

    Input:[[1,4],[3,5],[0,5],[4,7],[6,8],[7,10],[9,12],[11,14]]
    Output:4
    Input:[[1,2],[2,3],[3,4]]
    Output:3
    Input:[[1,10]]
    Output:1
    python

    The short version

    You manage a single conference room. A naive scheduler picks meetings by importance or length. A greedy scheduler always picks whichever meeting ends soonest — leaving the room free for as many future bookings as possible. Counterintuitively, this "earliest finisher first" rule — with zero lookahead — is provably optimal via an exchange argument: swapping any other first pick for the earliest-ending one never reduces the total count.

    In more depth

    Greedy algorithms build a solution incrementally, always taking the locally optimal option without revisiting previous choices. The decisive question is: does the greedy choice property hold? — meaning a globally optimal solution always includes the greedy first choice.

    Activity Selection is the canonical greedy success. After sorting by end time, the algorithm scans left-to-right and selects each activity whose start time >= lastEnd. The proof is an exchange argument: suppose an optimal solution starts with activity B instead of the earliest-finishing A. Since end(A) <= end(B), replacing B with A produces a solution that is still valid and has the same count — so including A is never worse. By induction, the greedy solution is globally optimal.

    The same "sort by end" key powers related problems: Interval Scheduling Maximization (maximize tasks on one machine), and LeetCode 435 Non-overlapping Intervals (minimum removals = total − greedy count). Interval Partitioning (minimize conference rooms) instead uses a min-heap keyed on room end times.

    Other greedy classics include Fractional Knapsack (sort by value/weight ratio; indivisible items break this), Huffman Coding (always merge two lowest-frequency nodes), Dijkstra's shortest path (relax the closest unvisited vertex), and Kruskal's MST (add the cheapest edge that doesn't form a cycle).

    Greedy fails when local choices foreclose globally better branches — 0/1 Knapsack and shortest path with negative edges need DP or more careful relaxation.

    When to reach for this

    • Select maximum items from a set of overlapping intervals
    • "Schedule as many as possible" or "finish earliest first" phrasing
    • Minimize number of resources (rooms, machines) to serve all requests
    • Fractional resource allocation where items are divisible
    • Exchange argument holds: swapping the greedy first choice never worsens the solution
    • Keywords: interval scheduling, activity selection, greedy choice property, non-overlapping

    Interview Questions

    Google
    Meta
    Amazon
    Google
    Facebook
    Apple
    Microsoft
    Amazon
    Google
    Amazon
    Bloomberg

    Love this visualization?

    Sign up to track your progress, earn achievements, use the AI assistant, and access your personal learning dashboard.

    100% free • No credit card required