// 返回都是 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;
}
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;
}
};
模板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;
}
};
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;
}
};
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;
}
};
// 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;
}
};
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 .. 1
cnt += pile / x;
if (pile % x != 0) cnt++;
}
return cnt <= h;
}
};
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;
}
};
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
// 大于等于 最小 模板1
int 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];
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
// 大于等于最小值模板1
while (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;
// 小于等于最大值模板2
while (l < r) {
int mid = ((l - r + 1) >> 1) + r;
if (nums[mid] <= target) l = mid;
else r = mid - 1;
}
return {r1, r};
}
};
class Solution {
public:
int splitArray(vector<int>& nums, int k) {
// 最大值最小 模板1
int 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;
}
};