We have a group of people, each with a known weight, and we need to ferry everyone using the fewest boats possible. Each boat has a weight limit and holds at most two people. The "at most two" rule shapes everything: even if three lightweight people would fit under the weight limit, a boat can only take two.
The question becomes: how do we pair people so that as many boats as possible carry two riders? The fewer solo riders, the fewer total boats.
Pairing works best when we match the heaviest person who still needs a boat with the lightest person available. If even the lightest person cannot share a boat with the heaviest, no one can, and the heaviest rides alone. Both approaches below apply this rule; they differ in how fast they find the heaviest and lightest remaining people.
1 <= people.length <= 5 * 10^4 → With n up to 50,000, O(n log n) sorting plus a linear pass fits comfortably. An O(n^2) approach that rescans the array for every boat is around 2.5 billion operations in the worst case, which is too slow.1 <= people[i] <= limit <= 3 * 10^4 → Every person's weight is at most the limit, so everyone fits in a boat alone if necessary. There is no "impossible" person.The heaviest person needs a boat no matter what, so assign them one. Their best possible partner is the lightest remaining person: if even that pairing exceeds the limit, no pairing involving the heaviest person works, and they ride alone. Repeat until everyone has a boat.
The choice of partner matters. Pairing each person with the first partner that fits can waste capacity. For people = [1, 1, 4, 4] and limit = 5, pairing the two 1s together leaves the two 4s to ride alone, for 3 boats, while pairing each 1 with a 4 uses 2 boats. Always taking the heaviest and lightest remaining people avoids this.
Without sorting, finding the heaviest and lightest remaining people requires scanning the whole array on every pass, which makes this O(n^2).
used of size n and a counter remaining = n.boats = 0.remaining > 0:remaining, increment boats.limit, put them on the same boat: mark them used and decrement remaining.boats.Loading animation...
used array tracks which people have already been assigned to a boat.The algorithm produces the correct answer but spends almost all its time rescanning the array. Sorting puts the lightest person at one end and the heaviest at the other, so two pointers moving inward can replace the repeated scans.
Sort the people by weight. The lightest person is now at the front, the heaviest at the back, so the two people the greedy rule cares about sit at the two ends of the array. Two pointers track them: light starting at index 0 and heavy starting at the last index.
For each boat, put the heaviest remaining person on it (they need a boat regardless). Then check whether the lightest remaining person can join: if people[light] + people[heavy] <= limit, they share the boat and both pointers move inward. Otherwise the heavy person rides alone and only the heavy pointer moves.
An exchange argument shows the greedy choice is safe. Take any optimal assignment in which people[light] + people[heavy] <= limit but the two do not share a boat. The heaviest person rides with some partner y or alone, and the lightest rides with some z or alone. Rearrange so the heaviest and lightest share one boat and y and z share another. The new (y, z) boat fits because z weighs no more than the heaviest person, so y + z <= y + heaviest <= limit. The rearrangement uses no extra boats, so pairing heaviest with lightest is always at least as good. And when even the lightest person exceeds the limit with the heaviest, no partner works, so sending the heaviest alone gives up nothing.
people array in ascending order.light = 0 and heavy = people.length - 1.boats = 0.light <= heavy:people[light] + people[heavy] <= limit, the lightest and heaviest can share a boat. Move light forward.heavy backward.boats.boats.Loading animation...