题目翻译:
你是一个产品经理,目前带领团队开发新产品。不幸的是,你的产品的最新版本未通过质量检查。由于每个版本都是在前一个版本基础上开发的版本,所以一旦某个版本坏了,他后面的所有版本都会坏。
假设你有N版本〔1,2,…,n),版本n是最新开发的版本,你想找到的第一个坏的,这导致所有以下的人是不好的。
给你一个API,bool isbadversion(vertion ),他将用来判断当前版本编号的版本是否是坏的,如果是坏的他将返回true。实现一个功能,找到的第一个坏的版本。你应该尽量减少调用API函数的次数。
分析:DONE
典型的二分搜索问题,注意截止条件即可!
显然如果当前版本释怀的,那么他后面一定全部是坏的,我们要找的第一个坏的一定就在包含了自身的前面。
如果当前版本是好的,那么第一个坏的版本一定在后面(不包含当前)。
也就是说答案始终被压缩在[low,high]中,当两者相等时无需再继续判断(见第二种写法);
时间复杂度:O(lg(n)),空间复杂度:O(1)
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int low=1,high=n;
while(low<=high)
{
int mid=low+(high-low)/2;//测试案例有超大数,这样写更安全
if(isBadVersion(mid))//如果是坏的版本
high=mid-1; //则一定在包括mid的左边(代码写成没有包括mid,所以low=high继续误差判断一次即可)
else//如果是好的,则一定在mid的右边
low=mid+1;
}
return low;
}
};
这样跌或许二分意义更加明确:
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int low=1, high=n;
while(low<high) {
int mid=low + (high-low)/2;
if(isBadVersion(mid))
high = mid; //则一定在包括mid的左边(代码写成包括mid,所以low=high不用继续判断了)
else
low = mid + 1; //则一定在不包括mid的右边
}
return low;
}
};
联动上一个问题:<LeetCode OJ> 35. Search Insert Position
针对典型的二分搜索写法,low和high中的有一个必须进行跨步移动(即必须在mid的基础上+1或者-1),否则死循环。如果跨步移动不符合实际的意义,截止条件再进行一次误差判断即可!
注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!
原文地址:http://blog.csdn.net/ebowtang/article/details/50735869
原作者博客:http://blog.csdn.net/ebowtang
本博客LeetCode题解索引:http://blog.csdn.net/ebowtang/article/details/50668895