881. Boats to Save People - Explanation
Description
You are given an integer array people where people[i] is the weight of the ith person, and an infinite number of boats where each boat can carry a maximum weight of limit. Each boat carries at most two people at the same time, provided the sum of the weight of those people is at most limit.
Return the minimum number of boats to carry every given person.
Example 1:
Input: people = [5,1,4,2], limit = 6
Output: 2Explanation:
First boat [5,1].
Second boat [4,2].
Example 2:
Input: people = [1,3,2,3,2], limit = 3
Output: 4Explanation:
First boat [3].
Second boat [3].
Third boat [1,2].
Fourth boat [2].
Constraints:
1 <= people.length <= 50,0001 <= people[i] <= limit <= 30,000
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Sorting - Understanding how to sort arrays and when sorting enables efficient solutions
- Two Pointers - Using two pointers from opposite ends of a sorted array to find optimal pairings
- Greedy Algorithms - Making locally optimal choices (pairing heaviest with lightest) to achieve global optimum
1. Sorting + Two Pointers
Intuition
Since each boat can carry at most two people and has a weight limit, we want to pair the heaviest person with the lightest person when possible. By sorting the weights, we can use two pointers: one at the heaviest person and one at the lightest. If they can share a boat, we move both pointers; otherwise, the heaviest person takes a boat alone.
Algorithm
- Sort the
peoplearray in ascending order. - Initialize two pointers:
leftat index0,rightat the last index. - Initialize a boat counter to
0. - While
leftis less than or equal toright:- Calculate the remaining capacity after placing the heaviest person (at
right). - Decrement
rightand increment the boat count. - If the lightest person (at
left) fits in the remaining capacity andleftis still valid, incrementleft.
- Calculate the remaining capacity after placing the heaviest person (at
- Return the boat count.
Time & Space Complexity
- Time complexity:
- Space complexity: or depending on the sorting algorithm.
2. Counting Sort
Intuition
When the range of weights is limited, counting sort can be faster than comparison-based sorting. We count the frequency of each weight, then reconstruct the sorted array. After sorting, we apply the same two-pointer greedy strategy as before.
Algorithm
- Find the maximum weight in the array.
- Create a count array of size
(max + 1)and count the frequency of each weight. - Reconstruct the sorted array by iterating through the count array.
- Apply the two-pointer approach:
- Initialize
leftat0andrightat the end. - While
leftis less than or equal toright:- The heaviest person takes a boat.
- If the lightest person fits with them, include them too.
- Initialize
- Return the boat count.
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
m = max(people)
count = [0] * (m + 1)
for p in people:
count[p] += 1
idx, i = 0, 1
while idx < len(people):
while count[i] == 0:
i += 1
people[idx] = i
count[i] -= 1
idx += 1
res, l, r = 0, 0, len(people) - 1
while l <= r:
remain = limit - people[r]
r -= 1
res += 1
if l <= r and remain >= people[l]:
l += 1
return resTime & Space Complexity
- Time complexity:
- Space complexity:
Where is the size of the input array and is the maximum value in the array.
Common Pitfalls
Forgetting to Sort the Array First
The two-pointer approach only works on sorted arrays. Attempting to pair people without sorting will not produce the minimum number of boats because you cannot guarantee pairing the heaviest with the lightest.
Trying to Fit More Than Two People per Boat
The problem states each boat can carry at most 2 people, regardless of weight. A common mistake is trying to fit three or more light people in one boat.
# Wrong: trying to fit multiple light people
while l <= r and remain >= people[l]:
remain -= people[l]
l += 1 # Might add more than 2 people totalNot Moving the Right Pointer First
The heaviest person always needs a boat. A mistake is checking if the lightest person fits first, which can lead to incorrect pointer movement when the lightest person alone exceeds the remaining capacity.
Sign in to join the discussion