[LeetCode] 875. Koko Eating Bananas 科科吃香蕉



Koko loves to eat bananas.  There are N piles of bananas, the i-th pile has piles[i] bananas.  The guards have gone and will come back in H hours.html

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

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

Return the minimum integer K such that she can eat all the bananas within Hhours.數組

Example 1:less

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

Example 2:ide

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:this

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



這道題說有一隻叫科科的猩猩,很是的喜歡吃香蕉,如今有N堆香蕉,每堆的個數可能不一樣,科科有H小時的時間來吃。要求是,每一個小時內,科科只能選某一堆香蕉開始吃,若科科的吃速固定爲K,即使在一小時內科科已經吃完了該堆的香蕉,也不能換堆,直到下一個小時才能夠去另外一堆吃。爲了健康,科科想盡量的吃慢一些,但同時也想在H小時內吃完全部的N堆香蕉,讓咱們找出一個最小的吃速K值。那麼首先來想,既然每一個小時只能吃一堆,總共要在H小時內吃完N堆,那麼H必定要大於等於N,否則必定無法吃完N堆,這個條件題目中給了,因此就不用再 check 了。咱們想一下K的可能的取值範圍,當H無窮大的時候,科科有充足的時間去吃,那麼就能夠每小時只吃一根,也能夠吃完,因此K的最小取值是1。那麼當H最小,等於N時,那麼一個小時內必須吃完任意一堆,那麼K值就應該是香蕉最多的那一堆的個數,題目中限定了不超過 1e9,這就是最大值。因此要求的K值的範圍就是 [1, 1e9],固定的範圍內查找數字,固然,最暴力的方法就是一個一個的試,憑博主多年與 OJ 抗衡的經驗來講,基本能夠不用考慮的。那麼二分查找法就是不二之選了,咱們知道經典的二分查找法,是要求數組有序的,而這裏香蕉個數數組又不必定是有序的。這是一個很好的觀察,可是要弄清楚究竟是什麼應該是有序的,要查找的K是吃速,跟香蕉堆的個數並無直接的關係,而K所在的數組其實應該是 [1, 1e9] 這個數組,其自己就是有序的,因此二分查找沒有問題。實際上這是博主以前那篇總結帖 LeetCode Binary Search Summary 二分搜索法小結 中的第四類 - 用子函數看成判斷關係。當求出了 mid 以後,須要統計用該速度吃完全部的香蕉堆所須要的時間,統計的方法就是遍歷每堆的香蕉個數,而後算吃完該堆要的時間。好比 K=4,那麼假若有3個香蕉,須要1個小時,有4香蕉,仍是1個小時,有5個香蕉,就須要兩個小時,若是將三種狀況融合爲一個式子呢,就是用吃速加上香蕉個數減去1,再除以吃速便可,即 (pile+mid-1)/mid,你們能夠自行帶數字檢驗,是沒有問題的。算出須要的總時間後去跟H比較,若小於H,說明吃的速度慢了,須要加快速度,因此 left 更新爲 mid+1,不然 right 更新爲 mid,最後返回 right 便可,參見代碼以下:code


class Solution {
public:
    int minEatingSpeed(vector<int>& piles, int H) {
        int left = 1, right = 1e9;
        while (left < right) {
            int mid = left + (right - left) / 2, cnt = 0;
            for (int pile : piles) cnt += (pile + mid - 1) / mid;
            if (cnt > H) left = mid + 1;
            else right = mid;
        }
        return right;
    }
};



Github 同步地址:htm

https://github.com/grandyang/leetcode/issues/875



相似題目:

Minimize Max Distance to Gas Station



參考資料:

https://leetcode.com/problems/koko-eating-bananas/

https://leetcode.com/problems/koko-eating-bananas/discuss/152324/C%2B%2BJavaPython-Binary-Search



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索