[二分搜索] lc875 Koko Eating Bananas

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

        二分搜索的一个主要难点在于确定搜索的空间。比较容易有思路的问题类型是对于已经排好序的数组查找特定数据,使用下标作为二分的搜索对象即可。

        另一种稍微有一点难度的是对所有可能的解在[minVal, maxVal] 区间进行二分搜索,判断当前解是否满足要求(但是题目做多了也是可以总结出套路的)。一般而言,所求的解存在一个边界条件要求,比如最小的满足条件的解,或者第k个满足条件的解,或者恰好等于某个数的解。比较经典的问题是,在从上到下,从左到右排好序的二维矩阵中找到特定的解,它看起来和类型一很像,但实际上我们无法通过下标进行二分,因为矩阵不是严格排好序的,只是部分数据满足有序条件。

         对于二分快速查找,C++的STL有几个比较好用的库,如下:

         binary_search(v.begin(),v.end(),num); // 二分查找数字num是否存在(返回bool)

         lower_bound(v.begin(), v.end(), num); // 二分查找第一个大于等于num的数字(返回迭代器)

         upper_bound(v.begin(), v.end(), num); // 二分查找第一个大于num的数字(返回迭代器)

        该题十分类似于猜数字,也就是在一定的求解空间中找到最小满足条件的值,使得KoKo能够以最慢的速度在特定时间内吃完所有香蕉。

class Solution {
public:
    bool IsValid(vector<int>& piles, int k, int H)
    {
        int hour = 0;
        for(auto& cur : piles)
        {
            hour += cur / k + ((cur % k) ? 1 : 0);
            if(hour > H) return false;
        }
        return true;
    }
    int minEatingSpeed(vector<int>& piles, int H) {
        int low = 1;
        int high = *max_element(piles.begin(), piles.end());
        while(low < high)
        {
            int mid = low + (high - low) / 2;
           
            if(IsValid(piles, mid, H))
            {
                high = mid;
            }
            else
            {
                low = mid + 1;
            }
        }
        return high;
    }
};

猜你喜欢

转载自www.cnblogs.com/fish1996/p/11260485.html
今日推荐