这道题目就是一个经典的二分法,但是在求mid的时候有个小陷阱。
在二分查找中,选取mid 的方法一般为
mid = (left + right)>>1
如果使用的编程语言会有整数溢出的情况(例如 C++,Java),那么可以用
left + (right - left)/2
代替前者。由于/和%的效率较低(约低一个量级),这里我们通常会选择用>>代替/,所以问题又来了,用
left + (right - left)>>1
算法总是但是超时。为什么呢?运算发优先级在作祟!摘录运算符优先级(科学百科)如下
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | 双目运算符 |
所以此处一定要加括号!如下才是最精准的表达式:
mid = left + ((right - left)>>1);
另附上该题的题解:
class Solution {
public:
int firstBadVersion(int n) {
int left = 1, right = n;
while (left < right) {
int mid = left + ((right - left)>>1);
if (isBadVersion(mid))
right = mid;
else
left = mid+1;
}
return left;
}
};