此题解采用了计数排序和双指针技术来解决问题。首先,创建一个计数数组来存储每个可能的体重值的人数。然后初始化答案为人数总和,假设每个人都单独乘坐一艘船。使用双指针技术,一个指针从最轻的体重开始,另一个从最重的体重开始,尝试将两个体重的人配对乘坐同一艘船。如果可以配对,则减少相应的人数和所需的船数。当两个指针相遇时,停止配对,并检查最后剩余的同体重人是否可以成对乘坐。
时间复杂度: O(n + limit)
空间复杂度: O(limit)
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
count = [0] * (limit + 1) # 创建计数数组,存储每个体重的人数
for w in people:
count[w] += 1 # 填充计数数组
ans = len(people) # 初始假设每人独自一船
l, r = 1, limit - 1 # 设置双指针,分别指向最轻和最重
while l < r:
while l < r and count[l] == 0: l += 1 # 找到下一个有人的最轻体重
r = min(r, limit - l) # 确保两人体重之和不超过limit
while l < r and count[r] == 0: r -= 1 # 找到下一个有人的最重体重
if l >= r: break # 如果指针重合或交叉,停止配对
if count[l] >= count[r]:
count[l] -= count[r] # 配对并减少相应的人数
ans -= count[r] # 减少船数
r -= 1
else:
count[r] -= count[l]
ans -= count[l]
l += 1
return ans - (count[l] // 2 if l * 2 <= limit else 0) # 处理剩余同体重人是否可以成对乘船