278. 第一个错误的版本
278. 第一个错误的版本
题目
You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.
Suppose you have n
versions [1, 2, ..., n]
and you want to find out the first bad one, which causes all the following ones to be bad.
You are given an API bool isBadVersion(version)
which returns whether version
is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.
Example 1:
Input: n = 5, bad = 4
Output: 4
Explanation:
call isBadVersion(3) -> false
call isBadVersion(5) -> true
call isBadVersion(4) -> true
Then 4 is the first bad version.
Example 2:
Input: n = 1, bad = 1
Output: 1
Constraints:
1 <= bad <= n <= 2^31 - 1
题目大意
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n
个版本 [1, 2, ..., n]
,你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version)
接口来判断版本号 version
是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
解题思路
使用二分查找。
将左右边界分别初始化为 1
和 n
,其中 n
是给定的版本数量。设定左右边界之后,每次都依据左右边界找到其中间的版本,检查其是否为正确版本。如果该版本为正确版本,那么第一个错误的版本必然位于该版本的右侧,缩紧左边界;否则第一个错误的版本必然位于该版本及该版本的左侧,缩紧右边界。
这样每判断一次都可以缩紧一次边界,而每次缩紧时两边界距离将变为原来的一半,因此至多只需要缩紧 O(log n)
次。
代码
/**
* @param {function} isBadVersion()
* @return {function}
*/
var solution = function (isBadVersion) {
/**
* @param {integer} n Total versions
* @return {integer} The first bad version
*/
return function (n) {
let left = 1;
let right = n;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (isBadVersion(mid)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
};
};
相关题目
题号 | 标题 | 题解 | 标签 | 难度 |
---|---|---|---|---|
34 | 在排序数组中查找元素的第一个和最后一个位置 | [✓] | 数组 二分查找 | |
35 | 搜索插入位置 | [✓] | 数组 二分查找 | |
374 | 猜数字大小 | [✓] | 二分查找 交互 |