题目:
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-bad-version
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
拓展:
二分法是一个非常高效的算法,它常常用于计算机的查找过程中。
在用二分法进行查找时,查找对象的数组必须是有序的,即各数组元素的次序是按其值的大小顺序存储的。其基本思想是先确定待查数据的范围(可用 [left,right] 区间表示),然后逐步缩小范围直到找到或找不到该记录为止。
具体做法是:先取数组中间位置(mid=(left+right)/2)的数据元素与给定值比较。若相等,则查找成功;否则,若给定值比该数据元素的值小(或大),则给定值必在数组的前半部分[left,mid-1](或后半部分[mid+1,right]),然后在新的查找范围内进行同样的查找。如此反复进行,直到找到数组元素值与给定值相等的元素或确定数组中没有待查找的数据为止。
因此,二分查找每查找一次,或成功,或使查找数组中元素的个数减少一半,当查找数组中不再有数据元素时,查找失败。
二分法查找是一种非常高效的搜索方法,主要原理是每次搜索可以抛弃一半的值来缩小范围。其时间复杂度是O(log2n),一般用于对普通搜索方法的优化。
二分法的适用情况一般满足以下几点:(1)该数组数据量巨大,需要对处理的时间复杂度进行优化;(2)该数组已经排序;(3)一般要求找到的是某一个值或一个位置。
https://blog.csdn.net/u012194956/article/details/79103843
https://www.cnblogs.com/cs-whut/p/11212022.html
/**
Problem:
第一个错误的版本
https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/8/sorting-and-searching/53/
@author:Gallery
*/
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
/**
注意:由题意可知判断是否bad的API已知。按照题目要求尽可能少调用API
思路:本题本质上是一个查找类题目
思路一:暴力法,从头往后遍历
思路二:二分法
*/
///暴力法:超时间
int firstBadVersion1(int n)
{
int i = 1;
for(; i<=n; ++i)
{
if(isBadVersion(i))
{
return i;
}
}
return n;
}
///二分法
int firstBadVersion(int n)
{
int mid,i = 1; ///从位置1开始
while(i<=n){
mid = i+(n-i)/2; ///mid为减半操作
if(isBadVersion(mid)){
///若是BadVersion,则查找原数组前半部分
n = mid-1;
}else{
///若不是BadVersion,则查找原数组后半部分
i = mid +1;
}
}
return i;
}