【LeetCode】1014. Capacity To Ship Packages Within D Days + 875. Koko Eating Bananas(二分搜索)

【LeetCode】1014. Capacity To Ship Packages Within D Days + 875. Koko Eating Bananas(二分搜索)

1014. Capacity To Ship Packages Within D Days

题目

A conveyor belt has packages that must be shipped from one port to another within D days.

The i-thpackage on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.

Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within Ddays.

Example 1:

Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
Output: 15
Explanation: 
A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10

Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. 

Example 2:

Input: weights = [3,2,2,4,1,4], D = 3
Output: 6
Explanation: 
A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4

Example 3:

Input: weights = [1,2,3,1,1], D = 4
Output: 3
Explanation: 
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1

Note:

1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500

思路

这题首先要明确要求的 “船容量” 的取值范围:
(1)最小值 smallest:最大的weight[i]
(2)最大值 largest :所有weight[i]的和。
也就是说,最终求得的 capacity 的取值范围是 [smallset, largest],而具体是这个区间中的哪个值,则可以采用二分搜索。

代码

class Solution {
public:
	// 该函数返回的是:如果船容量为a,则需要几天运完
    int days(int a, vector<int>& weights) {
        int i, j, k;
        j = 1;
        k = a;
        for(i=0; i<weights.size(); ++i) {
            if(k >= weights[i]) {
                k -= weights[i];
            }
            else {
                k = a - weights[i];
                j++;
            }
        }
        return j;
    }

    int bsearch(vector<int>& weights, int l, int r, int d) {
        int mid = (l + r) / 2;
        int k = days(mid, weights);
        if(k < d) {  // 如果所需天数小于d,说明船容量还可以更小
            if(l < mid-1)
                return bsearch(weights, l, mid-1, d);
            else
                return l;
        }
        else if(k > d) {  //如果天数大于d,说明船容量不够大
            if(mid+1 < r)
                return bsearch(weights, mid+1, r, d);
            else
                return r;
        }
        return mid;
    }

    int shipWithinDays(vector<int>& weights, int D) {
        int i, j, k, lar, ans;
        ans = lar = 0;

        for(i=0; i<weights.size(); ++i) {
            ans += weights[i];
            lar = max(lar, weights[i]);
        }

        j = bsearch(weights, lar, ans, D);
        if(days(j, weights) > D) {
            while(days(j, weights) > D) {
                ++j;
            }
            return j;
        }
        while(j - 1 >= lar && days(j-1, weights) <= D) {
            j--;
        }

        return j;

    }
};

Leetcode 的 875. Koko Eating Bananas 和该题类似。

875. Koko Eating Bananas

题目

Koko loves to eat bananas. There are N piles of bananas, the i-thpile has piles[i] bananas. The guards have gone and will come back in Hhours.

Koko can decide her bananas-per-hour eating speed of K. Each hour, she chooses some pile of bananas, and eats Kbananas from that pile. If the pile has less than Kbananas, she eats all of them instead, and won’t eat any more bananas during this hour.

Koko likes to eat slowly, but still wants to finish eating all the bananas before the guards come back.

Return the minimum integer Ksuch that she can eat all the bananas within Hhours.

Example 1:

Input: piles = [3,6,7,11], H = 8
Output: 4

Example 2:

Input: piles = [30,11,23,4,20], H = 5
Output: 30

Example 3:

Input: piles = [30,11,23,4,20], H = 6
Output: 23

Note:

1 <= piles.length <= 10^4
piles.length <= H <= 10^9
1 <= piles[i] <= 10^9

思路

这题跟 1014 那题是一样的,可以采用二分搜索来做。
首先明确 K 的取值范围:
(1)最小 :1;
(2)最大:piles[i]中的最大值。
明确范围后,就可以利用二分搜索了。

代码

class Solution {
public:
    int gethours(vector<int>& piles, int k) {
        int i, j, a, b;
        j = 0;
        for(i=0; i<piles.size(); ++i) {
            if(piles[i] % k == 0) {
                j = j + piles[i] / k;
            }
            else {
                j = j + piles[i] / k + 1;
            }
        }
        return j;
    }

    int bsearch(vector<int>& piles, int l, int r, int h) {
        int i, j, k, mid;
        mid = (l + r) / 2;

        j = gethours(piles, mid);

        if(j < h) {
            if(l >= mid-1) return l;
            return bsearch(piles, l, mid-1, h);
        }
        if(j > h) {
            if(r <= mid+1) return r;
            return bsearch(piles, mid+1, r, h);
        }
        return mid;
    }

    int minEatingSpeed(vector<int>& piles, int H) {
        int i, j, k, s, l;

        s = 1;
        l = 0;
        for(i=0; i<piles.size(); ++i) {
            piles[i] > l ? l = piles[i] : l = l;
        }

        i = bsearch(piles, s, l, H);
        j = gethours(piles, i);
        if(j > H) {
            while(gethours(piles, i) > H) {
                i++;
            }
            return i;
        }
        while(i-1 >0 && gethours(piles, i-1) == H) {
            i--;
        }
        return i;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值