278.第一个错误的版本

题目描述

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。
由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。
实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例 1:

  1. 输入:n = 5, bad = 4
  2. 输出:4
  3. 解释:
  4. 调用 isBadVersion(3) -> false
  5. 调用 isBadVersion(5) -> true
  6. 调用 isBadVersion(4) -> true
  7. 所以,4 是第一个错误的版本。

示例 2:

  1. 输入:n = 1, bad = 1
  2. 输出:1

提示:
1 <= bad <= n <= 2 - 1

解法

思路

尽量减少对 isBadVersion()的调用

因为一定有个错误的版本,那么n=1时,返回1

使用二分查找,双指针,low=1,high=n,mid=high/2

  1. 如果mid为false:

    1. mid+1 为true,那么第一个错误版本为mid+1
    2. mid+1 为fasle,那么第一个错误版本,在(mid+1, n]之间
  2. 如果mid为true:

    1. mid-1 为false,那么第一个错误版本为mid
    2. mid-1 为true,那么第一个错误版本在[1, mid-1)之间

实现

  1. Java
  1. public int firstBadVersion(int n) {
  2. if (n == 1) {
  3. return 1;
  4. }
  5. int left = 1, right = n;
  6. while (left <= right) {
  7. int mid = left + (right - left) / 2;
  8. if (isBadVersion(mid)) {
  9. right = mid - 1;
  10. } else {
  11. left = mid + 1;
  12. }
  13. }
  14. return left;
  15. }
  1. Python3
  1. def firstBadVersion(self, n):
  2. if n == 1:
  3. return 1
  4. left, right = 1, n
  5. while left <= right:
  6. mid = left + (right - left) // 2
  7. if isBadVersion(mid):
  8. right = mid - 1
  9. else:
  10. left = mid + 1
  11. return left
  1. Go
  1. func firstBadVersion(n int) int {
  2. if n == 1 {
  3. return 1
  4. }
  5. left, right := 1, n
  6. for left <= right {
  7. mid := left + (right-left)>>1
  8. if isBadVersion(mid) {
  9. right = mid - 1
  10. } else {
  11. left = mid + 1
  12. }
  13. }
  14. return left
  15. }