二分查找
class Solution { public: int mySqrt(int x) { if (x == 0) return 0; //特殊判断:0的平方根是0 //0: 0; 1: 1; 2: 1; 3: 1 //除上述4个数字外,其余数字x的平方根必小于等于其一半,即x/2 //由此,找到了二分查找的边界 int left = 1, right = x/2; while(left < right){ long long mid = left + (right-left+1)/2; long long s = mid * mid; if(s > x){ //找小于等于x的最大的s right = mid-1; } else{ left = mid; } } return left; } };
class Solution { public: int findDuplicate(vector<int>& nums) { int left = 1, right = nums.size()-1; //right为数组中数字的最大值 while(left < right){ int mid = left + (right-left)/2; int cnt = 0; for(int num: nums){ if(num <= mid) cnt++; } if(cnt > mid){ //说明重复的数字就在[left, mid]之间 right = mid; } else{ //说明重复的数字不在[left, mid]之间 left = mid + 1; } } return left; } };
875. 爱吃香蕉的珂珂
二分搜索的上界是数组piles中最大的数字,下界是1
class Solution { public: int hours(vector<int>& piles, int k){ //cout<<"k: "<<k<<endl; int ans = 0; for(int pile: piles){ if(pile <= k){ ans += 1; } else{ //ans += ceil((double)pile / k); //向上取整 ans += (pile + k - 1)/k; } } //cout<<"ans: "<<ans<<endl; return ans; } int minEatingSpeed(vector<int>& piles, int H) { //随着最小速度k增加,可以在H小时内吃掉所有香蕉的H减少 int left = 1; int right = *max_element(piles.begin(), piles.end()); while(left < right){ int mid = left + (right-left)/2; int hour = hours(piles, mid); if(hour > H){ //花费的时间比H大,则速度k增加 left = mid + 1; } else{ right = mid; } } return left; } };
LCP 12. 小张刷题计划