来源:力扣-二分查找
模板一:
/*模板 1 用于查找可以通过访问数组中的单个索引来确定的元素或条件。
1.二分查找的最基础和最基本的形式。
2.查找条件可以在不与元素的两侧进行比较的情况下确定(或使用它周围的特定元素)。
3.不需要后处理,因为每一步中,你都在检查是否找到了元素。如果到达末尾,则知道未找到该元素。初始条件:left = 0, right = length-1
终止:left > right
向左查找:right = mid-1
向右查找:left = mid+1
*/
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size() - 1;
while(left <= right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid - 1; }
}
// End Condition: left > right
return -1;
}
模板一:典型例题
/*
猜数字游戏的规则如下:
每轮游戏,系统都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了,系统会告诉你,你猜测的数字比系统选出的数字是大了还是小了。
你需要编写guessNumber(int n)来返回系统选择的随机的数字。
你可以通过调用一个预先定义好的接口 guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-1,1 或 0):
-1 : 你猜测的数字比系统选出的数字大
1 : 你猜测的数字比系统选出的数字小
0 : 恭喜!你猜对了!
示例 :
输入: n = 10, pick = 6
输出: 6
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/binary-search/xee4ev/
来源:力扣(LeetCode)
*/
/*
* Forward declaration of guess API.
* @param num your guess
* @return -1 if num is lower than the guess number
* 1 if num is higher than the guess number
* otherwise return 0
* int guess(int num);
*/
//————————————————————————————————————————————————————————————————————————————————————————
//代码如下
class Solution {
public:
int guessNumber(int n) {
int left = 0, right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
int flag = guess(mid);
if (flag == 0) {
return mid;
} else if (flag > 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return 0;
}
};
模板二:
/*
模板 2 是二分查找的高级模板。它用于查找需要访问数组中当前索引及其直接右邻居索引的元素或条件。
1.一种实现二分查找的高级方法。
2.查找条件需要访问元素的直接右邻居。
3.使用元素的右邻居来确定是否满足条件,并决定是向左还是向右。
4.保证查找空间在每一步中至少有 2 个元素。
5.需要进行后处理。 当你剩下 1 个元素时,循环 / 递归结束。 需要评估剩余元素是否符合条件。初始条件:left = 0, right = length
终止:left == right
向左查找:right = mid
向右查找:left = mid+1
*/
int binarySearch(vector<int>& nums, int target){
if(nums.size() == 0)
return -1;
int left = 0, right = nums.size();
while(left < right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid; }
}
// Post-processing:
// End Condition: left == right
if(left != nums.size() && nums[left] == target) return left;
return -1;
}
模板二:典型例题
/*第一个错误的版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/binary-search/xepthr/
来源:力扣(LeetCode)
*/
//——————————————————————————————————————————————————————————————————————————————————————————
//代码如下
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
long long left = 1, right = (long long)n + 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};