>RunTimeFix
BookStudyPracticeInterviewsYouTubeCoursesAbout
Log inGet Started

Table of Contents

01C++ Foundations & Input/Output02Loops & Direct Simulations03Arrays, Strings & Character Operations04Functions & Recursion05Strings & Character Operations06Structs, Lambdas & Structured Bindings07Preprocessor, Debug Macros & Compilation08Vectors, Pairs & Utility Algorithms09Sets, Maps & Multi-Containers10Sorting & Frequency Arrays11Complexity & Problem Solving12Basic Number Theory & Modular Arithmetic13Prefix Sums & Difference Arrays14Two Pointers & Sliding Window15Binary Search (Array & Answer Space)16Greedy Algorithms & Constructive Problems17Bit Manipulation & Masking18Stacks, Queues & Monotonicity19Disjoint Set Union (DSU)20Coordinate Compression, Fenwick Tree & Segment Tree21Graph Representation, DFS & BFS22Cycle Detection, Bipartite Checking & Topological Sort23Dijkstra, 0-1 BFS & Kruskal's MST24Rooted Trees — DFS, Subtree Size & Diameter25Binary Lifting, LCA & Euler Tour26Dynamic Programming — Foundations27Dynamic Programming — Knapsack & Subsets28Backtracking & Meet-in-the-Middle29Modular Inverse, Combinatorics & Fast Math30Hashing, String Algorithms & Geometry Basics
Study Library/Ch 16
Chapter 16 of 30

Greedy Algorithms & Constructive Problems

Learn the greedy paradigm, sorting-based greedy, interval scheduling, the exchange argument, and constructive algorithms.

The Greedy ParadigmSorting-Based GreedyInterval Scheduling (Activity Selection)The Exchange ArgumentConstructive Algorithms
Share:

Greedy Algorithms & Constructive Problems

A greedy algorithm makes the locally optimal choice at each step, hoping to find the global optimum. Greedy problems are common in contests because they reward clear thinking over complex code.

The Greedy Paradigm

  1. Sort the input in some order
  2. Process elements one by one
  3. Make the best local choice
  4. Never reconsider past choices

Greedy works when the problem has optimal substructure and the greedy choice property — the locally optimal choice leads to a globally optimal solution.

Sorting-Based Greedy

Example: Maximum Number of Activities

hljs cpp
// Sort by end time, greedily pick non-overlapping activities
vector<pair<int,int>> activities = {{1,4}, {3,5}, {0,6}, {5,7}, {3,8}, {5,9}, {6,10}, {8,11}};
sort(activities.begin(), activities.end(), [](const auto &a, const auto &b) {
    return a.second < b.second;
});

int count = 0, lastEnd = -1;
for (const auto &[start, end] : activities) {
    if (start >= lastEnd) {
        count++;
        lastEnd = end;
    }
}

Example: Minimum Platforms Required

hljs cpp
// Sort arrivals and departures separately
sort(arrivals.begin(), arrivals.end());
sort(departures.begin(), departures.end());

int platforms = 0, maxPlatforms = 0;
int i = 0, j = 0;
while (i < n) {
    if (arrivals[i] <= departures[j]) {
        platforms++;
        maxPlatforms = max(maxPlatforms, platforms);
        i++;
    } else {
        platforms--;
        j++;
    }
}

Interval Scheduling (Activity Selection)

The classic greedy problem: given intervals, select the maximum number of non-overlapping intervals.

hljs cpp
// Sort by end time
sort(intervals.begin(), intervals.end(), [](const auto &a, const auto &b) {
    return a.second < b.second;
});

int count = 0, lastEnd = INT_MIN;
for (const auto &[start, end] : intervals) {
    if (start >= lastEnd) {
        count++;
        lastEnd = end;
    }
}

Weighted Interval Scheduling (DP)

If intervals have weights and you want maximum total weight, it becomes a DP problem (not greedy).

The Exchange Argument

The formal way to prove a greedy algorithm is correct:

  1. Assume there's an optimal solution different from the greedy solution
  2. Show you can "exchange" one choice from the optimal with one from the greedy without making it worse
  3. Repeat until the optimal matches the greedy

Example Proof: Activity Selection

Suppose the greedy picks activity g and the optimal picks activity o for the same slot, where o.end > g.end. Replacing o with g leaves more room for subsequent activities, so the greedy is at least as good.

Constructive Problems

Some problems ask you to build an output (a permutation, a grid, a sequence) that satisfies certain conditions.

Example: Construct a Permutation with Specific Properties

hljs cpp
// Construct a permutation where a[i] != i (derangement)
vector<int> derange(n);
for (int i = 0; i < n; i++) derange[i] = i + 1;
rotate(derange.begin(), derange.begin() + 1, derange.end());
// Check: if n == 1, no derangement exists

Example: Construct a Binary Matrix

hljs cpp
// Fill a grid such that row sums and column sums match given values
// Sort rows by required sum, fill columns greedily

Common Constructive Patterns

  1. Parity arguments: if the answer requires even/odd counts
  2. Greedy construction: always place the largest/smallest available element
  3. Two-pass: fill from both ends toward the middle
  4. Pattern repetition: find a repeating pattern and tile it

Greedy vs DP vs Backtracking

TechniqueWhen to Use
GreedyLocally optimal choice leads to global optimum
DPOptimal substructure + overlapping subproblems
BacktrackingNeed to explore all possibilities (small constraints)

When in doubt, try greedy first. If it fails, think about DP.

Summary

  • Greedy: sort, process in order, make the best local choice
  • Activity selection: sort by end time, greedily pick non-overlapping
  • The exchange argument proves greedy correctness
  • Constructive problems: build the answer step by step, often using greedy or parity
  • If greedy doesn't work, the problem probably needs DP
Ch 15: Binary Search (Array & Answer Space)Ch 17: Bit Manipulation & Masking

Prefer reading offline? Download the full book as a PDF.

Download Free Book
>RunTimeFix

Practical programming education. Books, videos, courses, and hands-on learning for competitive programming, DSA, and software engineering.

RunTimeFix

  • About
  • YouTube
  • Book
  • Study Library
  • Courses

Learn

  • Competitive Programming
  • DSA
  • Development
  • Databases

Legal

  • Privacy
  • Terms
  • Refund Policy

RunTimeFix — debug → solve → run

© 2026 RunTimeFix. All rights reserved.