方法一:
class Solution {
public:
int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left <= right) {
int mid = (right-left)/2 + left;
// 只考虑一段,另一端不断缩进
/* 理解:
需要找到第一个bad的状态
若当前mid不是,则闭区间[left, mid]之间全不是
那第一个至少是mid+1的状态
其余什么都不用想
让另一边right = mid - 1即可(因为循环中是有=的)
*/
if (!isBadVersion(mid)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
};
方法二:
class Solution {
public:
int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left < right) {
int mid = (right-left)/2 + left;
// 只考虑一段,另一端不断缩进
/* 理解:
若mid是true
则有可能mid就是第一个true,因此不能偏移
false的话必然需要偏移才能到达true的状态
*/
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
// 退出循环时必然是 left == right
return left; // return right;一样
}
};
方法三:
class Solution {
public:
int firstBadVersion(int n) {
int left = 1;
int right = n;
int ans = -1;
while (left <= right) {
int mid = (right-left)/2 + left;
// 有等号的特殊写法
/* 理解:
只要是合格的就记录更新下
左右都偏移,但ans始终能记录合格的值
*/
if (isBadVersion(mid)) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
};