2021.4.26 每日leetcode

2021.4.26 每日leetcode(二分算法)

image-20210426153357851

最简单的就是一个一个试,然后找出船的最小承载量,船的最小承载量必须大于等于任何一个包裹的重量,我们只需要找到包裹的最大重量limit,把它当做船的最小承载量,看看是否满足,

如果满足就返回limit
如果不满足就增加船的承载量limit,继续判断……

public int shipWithinDays(int[] weights, int D) {
        //船的最小承载量必须大于等于任何一包裹的重量,不能小于,
        //否则这个包裹没法运
        int limit = 0;
        for (int weight : weights) {
            if (weight > limit)
                limit = weight;
        }

        while (true) {
            int days = 1;//运输包裹所需要的的天数
            int curWeight = 0;//目前船上包裹的重量
            for (int weight : weights) {
                if (curWeight + weight > limit) {
                    //如果当前的包裹放到船上,船上的承载量
                    //大于船的极限,那么当前的包裹就放到明天再运
                    days++;
                    curWeight = weight;
                } else {
                    //如果当前的包裹放到船上,还没有达到船
                    //的承载量,就放到这个船上当天运
                    curWeight += weight;
                }
            }
            //如果需要的天数大于D,说明不能满足,然后增加
            //船的最小承载量limit,进行下一轮循环。
            if (days > D) {
                limit++;
            } else {
                return limit;
            }
        }
    }

二分算法

因为船的极限limit必须大于等于包裹的最大重量(假设为left),小于等于所有包裹的重量(假设为right),那么船的最小承载量limit肯定是在[left,right]之间,我们每次枚举left和right之间的值mid,然后在判断,

如果mid不能满足,那么比mid小的都不能满足,这样我们可以排除一半的数量,
如果mid能满足,虽然mid能满足,但不一定是最小的,我们还要继续查找,直到找出最小的承载量即可。

    public int shipWithinDays(int[] weights, int D) {
        int left = 0;//最大包裹重量,也就是船的最小承载量
        int right = 0;//所有包裹的重量,也就是船的最大承载量
        for (int weight : weights) {
            if (weight > left)
                left = weight;
            right += weight;
        }
        //二分法查找
        while (left < right) {
            //先用中间的值判断是否满足条件
            int mid = left + (right - left) / 2;
            int days = 1;//需要的天数
            int curWeight = 0;//当前船上包裹的重量
            for (int weight : weights) {
                if (curWeight + weight > mid) {
                    //如果当前包裹放到船上,超过了船的极限,
                    //就放到明天再运
                    days++;
                    curWeight = weight;
                } else {
                    //如果当前的包裹放到船上,没超过船的极限,
                    //就把当前的包裹放到船上
                    curWeight += weight;
                }
            }
            if (days > D) {
                //需要的天数超了,说明船的极限小了,
                //下一轮循环要增加船的极限
                left = mid + 1;
            } else {
                //需要的天数没超,说明船的极限满足条件,
                //然后继续查找更小的满足条件的承载量
                right = mid;
            }
        }
        return left;
    }

摘自leetcode

  right = mid;
        }
    }
    return left;
}

摘自leetcode

作者:sdwwld
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值