881. 救生艇
给定数组people
。people[i]
表示第i
个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit
。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit
。
返回 承载所有人所需的最小船数 。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)
示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)
示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
提示:
- 1 <= people.length <= 5 * 10^4
- 1 <= people[i] <= limit <= 3 * 10^4
解题思路
考虑体重最轻的人:
- 若他不能与体重最重的人同乘一艘船,那么体重最重的人无法与任何人同乘一艘船,此时应单独分配一艘船给体重最重的人。从
people
中去掉体重最重的人后,我们缩小了问题的规模,变成求解剩余n−1
个人所需的最小船数,将其加一即为原问题的答案。 - 若他能与体重最重的人同乘一艘船,那么他能与其余任何人同乘一艘船,为了尽可能地利用船的承载重量,选择与体重最重的人同乘一艘船是最优的。从
people
中去掉体重最轻和体重最重的人后,我们缩小了问题的规模,变成求解剩余n−2
个人所需的最小船数,将其加一即为原问题的答案。
Go代码
func numRescueBoats(people []int, limit int) int {
if len(people) == 0 {
return 0
}
sort.Ints(people)
left,right := 0,len(people) - 1
cnt := 0
for left <= right {
// 看看是否还能额外带一人
if people[left] + people[right] <= limit {
left++
}
// 本趟一定至少救走那个体重最大的,救援趟数加一
cnt++
right--
}
return cnt
}