跳至主要內容

278. 第一个错误的版本


278. 第一个错误的版本open in new window

🟢   🔖  二分查找 交互  🔗 力扣open in new window LeetCodeopen in new window

题目

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 的次数。

解题思路

使用二分查找。

将左右边界分别初始化为 1n,其中 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在排序数组中查找元素的第一个和最后一个位置open in new window[✓]数组 二分查找
35搜索插入位置open in new window[✓]数组 二分查找
374猜数字大小open in new window[✓]二分查找 交互