接上一篇笔记:
这一章,我们看二分查找的两道例题
例题1:
1.1.题目要求:
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有
n个版本[1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。你可以通过调用
bool isBadVersion(version)接口来判断版本号version是否在单元测试中出错。实现一个函数==来查找第一个错误的版本==。你应该尽量减少对调用 API 的次数。
示例 1:
输入:
n = 5, bad = 4输出:
4解释:
调用
isBadVersion(3) -> false调用
isBadVersion(5) -> true调用
isBadVersion(4) -> true所以,
4是第一个错误的版本。
示例 2:
输入:
n = 1, bad = 1输出:1
提示:
1 <= bad <= n <= 231 - 1
1.2.解题思路:
这道题的题意有些难懂,刚看到时我还不知道在说啥
但细看后就知道,题目是让我们在众多版本中找到第一个错误的版本是哪一个
类似在一个表
[+++++*****]里找到第一个*号而题目让我们找到第一个
bad的状态这道题符合二分查找的条件
我们每次都取到中间值
middle,然后判断版本错误。即isBadVersion(middle)==如果是错误版本,那么错误的版本之后必然全是错误的,反之,正确的版本之前全是正确的==
根据这一点,我们来更新区间。
在循环的最后,区间就缩为一个点,返回
first即可
1.3.代码实现:
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
long middle,first=1,end = n;
while(first <= end){
middle = first + (end - first) / 2;
if(isBadVersion(middle))
end = middle - 1;
else
first = middle + 1;
}
return first;
}
};
例题2:
2.1.题目要求:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。
如果目标值不存在于数组中,返回==它将会被按顺序插入的位置==。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
- 输入:
nums = [1,3,5,6],target = 5- 输出: 2
示例 2:
- 输入:
nums = [1,3,5,6],target = 2- 输出: 1
示例 3:
- 输入:
nums = [1,3,5,6],target = 7- 输出: 4
示例 4:
- 输入:
nums = [1,3,5,6],target = 0- 输出: 0
示例 5:
- 输入:
nums = [1],target = 0- 输出: 0
提示:
- 1<=nums.length<=104
-104<=nums[i]<=104
nums为无重复元素的升序排列数组
-104<=target<=104
2.2.解题思路:
在一个数组里查找一个整数,而且是==有序,无重复元素且有范围的数组==,很显然可以使用==二分查找==来解决问题
这道题其实和上一道差不多,只不过多了一个要求,就是==如果数组里没有目标值,那么求出目标值应插入的位置==
opt。如果在循环中没能找到
target相应的位置,那么其位置应该在数组的末尾
2.3.代码实现:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int first = 0;
int end = nums.size() - 1; //定义target在左闭右闭的区间里,[left, right]
while (first <= end) {
int middle = first + ((end - first) / 2);
if (target < nums[middle]) {
end = middle - 1; // target在左区间,更新区间为[first, middle-1]
}
else if (nums[middle] < target) {
first = middle + 1; // target在右区间,更新区间为[middle + 1, end]
}
else {
return middle; //target == nums[middle]
}
}
return end + 1; //将target插在数组末尾
}
};
好了,二分查找就看到这,下一篇我们看双指针!