leetcode 881. Boats to Save People(救生船)

You are given an 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 = [1,2], limit = 3
Output: 1
Explanation: 1 boat (1, 2)

Example 2:

Input: people = [3,2,2,1], limit = 3
Output: 3
Explanation: 3 boats (1, 2), (2) and (3)

Example 3:

Input: people = [3,5,3,4], limit = 5
Output: 4
Explanation: 4 boats (3), (3), (4), (5)

Constraints:

1 <= people.length <= 5 * 104
1 <= people[i] <= limit <= 3 * 104

有限个人,无限个船,people数组中的元素表示人的重量,
一个船最多坐俩人,且不能超重,重量限制在limit。
问多少个船能把所有人渡过河。

思路:
简言之就是背包问题,一个包里面最多放俩数字,数字之和<=limit。问要多少个包。

首先排序是肯定要的。

可能会想到优先把小的塞进去,塞不下了再走到下一个数字。
但是这种情况呢,[1, 2, 4, 5], limit=6,
如果优先塞小的,需要[1, 2], [4], [5] 三个包,而最小是[1, 5], [2, 4]两个包的。

因为一个包最多放俩数字,可以考虑双指针。
1 <= people[i] <= limit 这个条件提示我们大的数字肯定能放进去,由于和是一定的,所以越大的放进去,就需要另一个数字越小。
这让我们想到什么,一个指针从右边往左走(从大到小),那么另一个指针就要从左往右走(从小到大)。

优先让大的先放进去,所以右边指针每次都向左走一步,船的个数+1。
如果左边小的能放进去,左边指针就往右走一步,放不进去,就留在原地。

终止条件:left <= right, 为什么是 " <= " 而不是 " < ",
比如[1, 3, 4, 5], limit=6, left在3这里不能再往右走,3没被放进去,直到right走到3这里才把它放进去。

    public int numRescueBoats(int[] people, int limit) {
        int result = 0;
        int left = 0;
        int right = people.length - 1;
        
        Arrays.sort(people);
        
        while(left <= right) {
            if(people[left] + people[right] <= limit) left ++;
            right --;
            result ++;
        }
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值