Greedy Algorithms · Greedy Fundamentals

Greedy Sorted Matching

Sorting both sides of a matching problem so the smallest-fitting pairing can always be made first, without ever needing to reconsider it.

  • 5 min read
  • 8 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach
  3. A second flavor: pair from both ends
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

Children with greed factors and cookies of different sizes, people and two-seat boats, tasks and workers of different skill: each asks how many pairs can be matched, and trying every matching is exponential. After sorting, one simple rule is provably optimal. Knowing why it's optimal is what tells you when a similar-looking rule isn't. This skill covers the two sorted sweeps and the exchange argument that proves them.

We'll go from simple to more technical:

  1. The pattern: sort both sides and give each child the smallest cookie that satisfies them.
  2. A second flavor: pair the heaviest with the lightest (boats).
  3. Where threshold matching shows up (resource allocation, scheduling, packing).
  4. What breaks it: one-sided sorting, boundary comparisons, neighbor pairing, other objectives.

The approach

Java

int findContentChildren(int[] greed, int[] cookies) {
    Arrays.sort(greed);
    Arrays.sort(cookies);
    int child = 0;
    for (int c = 0; child < greed.length && c < cookies.length; c++) {
        if (cookies[c] >= greed[child]) child++;     // smallest cookie that contents the least greedy child
        // otherwise this cookie is too small for every remaining child: skip it
    }
    return child;
}

Python

def find_content_children(greed: list[int], cookies: list[int]) -> int:
    greed = sorted(greed)
    child = 0
    for c in sorted(cookies):
        if child == len(greed):
            break
        if c >= greed[child]:
            child += 1                           # smallest cookie that contents the least greedy child
        # otherwise this cookie is too small for every remaining child: skip it
    return child

Two facts make the sweep correct. A cookie too small for the least greedy remaining child is too small for all of them, so discarding it loses nothing. And giving the least greedy child the smallest cookie that satisfies them is safe - an exchange argument: in any optimal matching, swap that cookie in for whatever the child got; the bigger cookie that's freed can only content more children, never fewer. Both sides must be sorted; with unsorted cookies, a large cookie can be used up on an easy child that a smaller cookie would have contented.

A second flavor: pair from both ends

Boats carry at most two people with total weight at most limit. Sort once and pair the heaviest remaining person with the lightest:

Java

int numRescueBoats(int[] people, int limit) {
    Arrays.sort(people);
    int boats = 0;
    for (int light = 0, heavy = people.length - 1; light <= heavy; heavy--) {
        if (people[light] + people[heavy] <= limit) light++;   // the lightest rides along if it fits
        boats++;                                              // the heaviest leaves now either way
    }
    return boats;
}

Python

def num_rescue_boats(people: list[int], limit: int) -> int:
    people = sorted(people)
    boats = 0
    light, heavy = 0, len(people) - 1
    while light <= heavy:
        if people[light] + people[heavy] <= limit:
            light += 1                           # the lightest rides along if it fits
        heavy -= 1
        boats += 1                               # the heaviest leaves now either way
    return boats

The heaviest person needs a boat no matter what. If anyone can share it, the lightest can, and choosing the lightest keeps every heavier person available for someone else. Pairing neighbors in sorted order looks similar but fails: weights [1, 2, 4, 5] with limit 6 give (1, 2), then 4 and 5 alone - 3 boats - while (1, 5) and (2, 4) need only 2.

Where you'll see it

Assigning tasks to workers by minimum required skill (use the least-skilled worker who qualifies, saving experts for hard tasks), packing two jobs per machine under a memory limit, and seating groups at tables of fixed size all use sorted matching.

Which tool for which job?

You needUse
Max matches when bigger always works for moresort both sides, smallest that fits
Pairs under a weight limitsort, then heaviest with lightest
Arbitrary compatibility ("A works with B and C")bipartite matching with augmenting paths
Different rewards per matchweighted assignment (Hungarian algorithm), not a count greedy
More than two per boatbin packing: greedy isn't optimal

Common mistakes

MistakeWhat happensDo this instead
Sorting only one sidethe exchange argument failssort both
> instead of >=exact fits rejectedmatch the problem's rule
Pairing neighbors[1, 2, 4, 5], limit 6: 3 boats instead of 2heaviest with lightest
First-fit on arbitrary compatibility1 match where 2 are possibleaugmenting paths
Count greedy with rewardsearns 1 instead of 10weighted assignment
The two-person rule with three seats3 boats where 2 sufficesearch or DP; it's bin packing

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. Why is it safe to throw away a cookie that can't content the least greedy remaining child?

Show answer

Every remaining child is at least as greedy as that child, so the cookie can't content any of them. Discarding it can't cost a match.

2. Why does the boat solution pair the heaviest person with the lightest rather than the next heaviest?

Show answer

The heaviest needs a boat regardless. If anyone fits with them, the lightest does, and taking the lightest leaves every heavier person free to pair elsewhere. Pairing neighbors can waste capacity: [1, 2, 4, 5], limit 6 needs 3 boats that way but 2 with (1, 5) and (2, 4).

3. What is an exchange argument?

Show answer

A proof that a greedy choice is safe: take any optimal solution, replace its choice with the greedy one, and show the result is still valid and no worse. Repeating the argument for each step shows the whole greedy solution is optimal.

Key takeaways

  • Sort both sides, then give the smallest sufficient resource to the least demanding request.
  • A resource too small for the smallest request is useless - skip it.
  • Two per container: pair the heaviest with the lightest, not with a neighbor.
  • Prove greedy rules with an exchange argument; they hold only for the objective they were proved for.

Quick revise

The whole skill on one page, for the night before an interview.

This page puts the lesson and the deep dive together. Skim it before practice or an interview, and go back to the full lesson for anything you don't recognize.

Pick the tool

You needUse
Threshold matchingsort both, smallest that fits
Pairs under a limitheaviest with lightest
Arbitrary compatibilityaugmenting paths
Weighted matchesHungarian / min-cost flow
3+ per binbin packing heuristics / search

Snippets worth knowing by heart

Java

Arrays.sort(g); Arrays.sort(s);
int child = 0;
for (int cookie : s) if (child < g.length && cookie >= g[child]) child++;
return child;

Python

def try_assign(u, seen):                 # Kuhn's augmenting path for bipartite matching
    for r in adj[u]:
        if r not in seen:
            seen.add(r)
            if match[r] == -1 or try_assign(match[r], seen):
                match[r] = u
                return True
    return False

The traps

  • One-sided sorting: the exchange argument needs both sides in order. Sort both.
  • Boundary comparisons: > instead of >= rejects exact fits. Match the problem's rule.
  • Neighbor pairing: pairing adjacent weights wastes boats. Pair the heaviest with the lightest.
  • First-fit on arbitrary compatibility: it finds fewer matches than possible. Use augmenting paths.
  • Count greedy with rewards: maximizing matches isn't maximizing reward. Use weighted assignment.

Staff-level points, one line each

  • Sorted greedy matched brute force on 300 cookie cases.
  • [[0, 1], [0]]: first-fit 1, augmenting paths 2.
  • Rewards [1, 10] with one cookie: count greedy earned 1, best 10.
  • Three per boat, [1, 3, 4, 5, 7], limit 10: greedy 3 boats, optimal 2.

Say it in an interview

  • "After sorting, the smallest cookie that fits is always safe. That's the exchange argument."
  • "Heaviest with lightest, because the heaviest needs a boat anyway."
  • "If compatibility is arbitrary, it's bipartite matching."
  • "If matches have values, it's weighted assignment."

Practice

This skill comes with 8 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Greedy Sorted Matching free

Assign Cookies

EasyFreeCoding problemJava · Python

You're handing out cookies. Child i is happy only with a cookie of size at least greed[i], and each child gets at most one cookie. Given the cookie sizes, return the largest number of children you can make happy.

Boats to Save People

MediumProCoding problemJava · Python

A rescue boat holds two people at most, and their combined weight can't go over limit. Given everyone's weight (none above limit), return the fewest boats that carry everyone.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Practice Greedy Sorted Matching free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime