// 返回都是 r// 区间划分为[l,mid] 和 [mid+1,r],选择此模板
int bsec1(int l, int r)
{while (l < r){int mid = (l + r)/2;//此处不加下面加if (check(mid)) r = mid;else l = mid + 1;}return r;
}// 区间划分为[l,mid-1] 和 [mid,r],选择此模板
int bsec2(int l, int r)
{while (l < r){int mid = ( l + (r + 1) ) /2;//此处加了,下面-if (check(mid)) l = mid;else r = mid - 1;}return r;
}
162 寻找峰值
class Solution {
public:int findPeakElement(vector<int>& nums) {/*模板 1*/int l = 0, r = nums.size() - 1;while (l < r) {int mid = (l + r) >> 1;if (nums[mid] > nums[mid + 1]) r = mid;else l = mid + 1;}return r;}
};
704 二分查找
模板1,注意判断找不到的情况
class Solution {
public:int search(vector<int>& nums, int target) {// 套哪个模板?// 当 nums[mid] >= target 时,r = mid// 所以第一个模板int l = 0, r = nums.size() - 1;while (l < r) {int mid = (l + r) / 2;if (nums[mid] >= target) r = mid;else l = mid + 1;}return nums[r] != target ? -1 : r;}
};
69 x 的平方根
class Solution {
public:
// 小于等于目标值的最大值
// 假设... l = mid ==> 第二个模板int mySqrt(int x) {int l = 0, r = x;while (l < r) {long mid = ((l - r + 1) >> 1) + r;if ((long)mid * mid <= x) {l = mid;}else{r = mid - 1;}}return r;}
};
35 搜索插入位置
class Solution {
public:int searchInsert(vector<int>& nums, int target) {// >= target 的最小值// 第一个模板int n = nums.size();int l = 0;int r = n;while(l < r) {int mid = (l + r) >> 1;if (nums[mid] >= target) r = mid;else l = mid + 1;}return r;}
};
278 第一个错误版本
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);class Solution {
public:int firstBadVersion(int n) {int l = 0, r = n;// if => r = mid ==> 第一个模板while (l < r) {int mid = r + ((l - r) >> 1);if (isBadVersion(mid)) r = mid;else l = mid + 1;}return r;}
};
875 爱吃香蕉 模板1
class Solution {
public:// 在某个最大值区间内最小 --> 第一个模板int minEatingSpeed(vector<int>& piles, int h) {int l = 1, r = (int)1e9;while (l < r) {int mid = ((l - r) >> 1) + r;// 可以在这个时间段内吃完if (check(mid, piles, h)) r = mid;else l = mid + 1;}return r;}// 速度设置为 x 能否在 h 小时内吃完bool check(int x, vector<int>& piles, int h) {int cnt = 0;for (auto pile : piles) {// 比如 11/5 = 2 .. 1cnt += pile / x;if (pile % x != 0) cnt++;}return cnt <= h;}
};
367 有效的完全平方数
class Solution {
public:bool isPerfectSquare(int num) {long long l = 0, r = num;while (l < r) {long long mid = r + ((l - r) >> 1);long long square = mid * mid;if (square >= num) r = mid;else l = mid + 1;}return r * r == num;}
};
744 寻找比目标字母大的最小字母
class Solution {
public:char nextGreatestLetter(vector<char>& letters, char target) {// 大于等于 最小 模板1int l = 0, r = letters.size() - 1;while (l < r) {int mid = (l + r) >> 1;if (letters[mid] > target) {r = mid;} else {l = mid + 1;}}if (letters[r] > target) return letters[r];else return letters[0];}
};
** 34 排序数组第一个和最后一个元素
class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;// 大于等于最小值模板1while (l < r) {int mid = ((l - r) >> 1) + r;if (nums[mid] >= target) r = mid;else l = mid + 1;}if (nums.empty() || nums[r] != target) return {-1, -1};int r1 = r;l = 0, r = nums.size() - 1;// 小于等于最大值模板2while (l < r) {int mid = ((l - r + 1) >> 1) + r;if (nums[mid] <= target) l = mid;else r = mid - 1;}return {r1, r};}
};
410 分割数组的最大值
class Solution {
public:int splitArray(vector<int>& nums, int k) {// 最大值最小 模板1int l = 0, r = (int)1e9;while (l < r) {int mid = (l + r) >> 1;if (check(mid, nums, k)) r = mid;else l = mid + 1;}return r;}bool check(int mid, vector<int>& nums, int k) {// 这个分法是否可分 k 份int curs = 1, cur = 0;// 初始为 1 份for (auto num : nums) {if ((cur + num) <= mid) cur += num;else {if (num > mid) return false;curs++;cur = num;}}return curs <= k;}
};