持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
374. 猜数字大小
思路:
代码:
class Solution {
public:
int guessNumber(int n) {
int l = 1, r = n;
while (l < r) {
int mid = l + (r - l)/2;
if (guess(mid) <= 0) r = mid;
else l = mid + 1;
}
return r;
}
};
278. 第一个错误的版本
思路:
代码:
class Solution {
public:
int firstBadVersion(int n) {
int l = 1, r = n;
while (l < r) {
int mid = l +(r - l) / 2;
if (isBadVersion(mid)) r = mid;
else l = mid + 1;
}
return r;
}
};
274. H 指数
思路:
代码:
class Solution {
public:
int hIndex(vector<int>& citations) {
sort (citations.begin(), citations.end());
// if (citations.size() == 1 && citations[0] == 0) return 0;
int h = 0, ans = 0;
for (int i = citations.size() - 1; i >= 0; i--) {
if (citations[i] >= citations.size() - i) {
h = citations.size() - i;
}
ans = max(h, ans);
}
return ans;
}
};
153. 寻找旋转排序数组中的最小值
思路:
代码:
class Solution {
public:
int findMin(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while(l < r) {
int mid = l + r + 1 >> 1;
if(nums[0] <= nums[mid]) {
l = mid;
} else {
r = mid - 1;
}
}
return r + 1 < nums.size() ? nums[r+1] : nums[0];
}
};
154. 寻找旋转排序数组中的最小值 II
思路
代码:
class Solution {
public:
int findMin(vector<int>& nums) {
// 恢复二段性
int n = nums.size();
int left = 0,right = n - 1;
while(left < right && nums[right] == nums[0]){
right--;
}
// 找到旋转点
while (left < right){
int mid = left + right + 1 >> 1;
if(nums[mid] >= nums[0]){
left = mid;
} else{
right = mid - 1;
}
}
return right + 1 < n ? nums[right + 1] : nums[0];
}
};
模板一:
区间左侧,找最小
{
while (l < r)
{
int mid = (l + r)/2;
if (nums[mid] >= target) r = mid;
else l = mid + 1;
}
return l;
}
模板二:
区间右侧,找最大
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = ( l + r + 1 ) /2;
if (nums[mid] <= target) l = mid;
else r = mid - 1;
}
return l;
}
while循环结束条件是l >= r,但为什么二分结束时我们优先取r而不是l?
二分的while循环的结束条件是l>=r,所以在循环结束时l有可能会大于r,此时就可能导致越界,因此,基本上二分问题优先取r都不会翻车。