二分查找 经典例题
2023-12-31 15:32:49
// 返回都是 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 .. 1
cnt += 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) {
// 大于等于 最小 模板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];
}
};
** 34 排序数组第一个和最后一个元素
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};
}
};
410 分割数组的最大值
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;
}
};
文章来源:https://blog.csdn.net/Algo_x/article/details/135256316
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!