这道题目就是一个经典的二分法,但是在求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;
}
};