LeetCode 278. First Bad Version

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 will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

题意:(直译)假设你是产品经理,目前正领导一个团队开发新产品。 不幸的是,产品的最新版本未通过质量检查。 由于每个版本都是基于以前的版本开发的,因此出错版本的后续所有版本也都存在错误。
假设有n个版本[1,2,...,n],要求找出第一个出现错误的版本,因为这会导致后续所有版本的错误。
现给定API: bool isBadVersion(version),它将返回该version版本是否存在错误。 实现一个函数来查找第一个错误版本。 同时应该尽量减少对API的调用次数。

即给定一系列数,找出其中第一个出错的数

思路:开始想的使用二分法,但因为left+right的原因而存在溢出问题

而且自己还把问题想复杂了,要先判断前一个版本是正确的,且后一个版本是错误的,才返回该第一个出错的版本

public int firstBadVersion(int n) {
            int left = 1, right = n, mid = 0;
            while(left <= right && mid + 1 <= n){
                mid = left + (right - left) / 2;//若mid = (left + right) / 2,left+right可能会溢出
                if((!isBadVersion(mid)) && isBadVersion(mid + 1))
                    return mid + 1;
                if(isBadVersion(mid))
                    right = mid - 1;
                else
                    left = mid + 1;
            }
            return 1;
        }

改进:使用LeetCode提供的说明

Scenario #1: isBadVersion(mid) => false

 1 2 3 4 5 6 7 8 9
 G G G G G G B B B       G = Good, B = Bad
 |       |       |
left    mid    right

isBadVersion(mid) = false,因此我们可以判断从left到mid都是good,因此left = mid + 1,下一次的范围变为[mid + 1, right]

Scenario #2: isBadVersion(mid) => true

 1 2 3 4 5 6 7 8 9
 G G G B B B B B B       G = Good, B = Bad
 |       |       |
left    mid    right

isBadVersion(mid) = true,因此我们可以判断mid是bad,但mid有可能是第一个bad,因此right = mid,下一次的范围变为[left, mid]

 

public int firstBadVersion(int n) {
        int left = 1, right = n, mid = 0;
        while(left < right){
            mid = left + (right - left) / 2;
            if(isBadVersion(mid))
               right = mid;
            else
                left = mid + 1;
        }
        return left;
    }

 

posted @ 2018-03-15 22:17  zeroingToOne  阅读(187)  评论(0编辑  收藏  举报