leetcode 278 第一个错误的版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 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
二分法一
这题相比于leetcode 704题稍微有点难度,leetcode 704
public int firstBadVersion(int n) {
int left=1;
int right=n;
while(left<right){
int mid=left+((right-left)>>1);
//是坏的版本,right赋值为mid;right可不可以赋值right=mid-1?
//可以,但是while循环中的条件就需要改变,见方法二。因为while循环
// 中的条件是left<right,即当left==right时退出循环,也就是left或
// 者right即为答案;
// 因为题目要找第一个坏的版本的序号,所以心里要有一种无限逼近的思
// 想,当mid是坏的版本,right就赋值为mid,但是不return,继续逼
// 近;当第二轮循环mid不是坏的版本,我们就需要将left赋值为mid+1,
// 因为mid肯定不是坏的版本,所以left不赋值mid。
// 最后一次循环比如left=5,right=6,mid算出为5;当5为坏的版本时,
// right赋值mid等于5;当5不是坏的版本时,left=mid+1=6;
// 不论哪种情况都满足left==right,所以退出循环,返回left或者right。
if(isBadVersion(mid)){
right=mid;
}else{
//不是坏的版本
left=mid+1;
}
}
return right; //或者返回left都可以
}
二分法二
public int firstBadVersion(int n) {
int left=1;
int right=n;
//while条件这么写其实给自己增加麻烦了,但是为了掌握二分法,大家可以都试试。
//这边条件结束是left>right,也就是left==right+1退出循环
while(left<=right){
int mid=left+((right-left)>>1);
//当mid是坏的版本,right=mid-1;但是这么写可能错过最终答案,
//比如版本中只有最后一个版本是错的,那right=mid-1就有可能错过;
//但是要注意while循环中的条件是left>right,即left==right+1退出循环;
//我们最后的答案返回的是left,也就是right+1,所以这一减一加又到 了正确答案。
if(isBadVersion(mid)){
right=mid-1;
}else{
left=mid+1;//不是坏的版本
}
}
return left;//这边只能返回left
}