[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 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 <= 231 - 1

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

 

话说这个叫李建超(音译)的哥们太赞了,自从 LeetCode 开始收费后,大多数的免费题都是这哥们出的,还写了所有的 test cases,32 个赞。这道题说是有一系列版本,其中有一个版本是坏的,而且后面跟着的全是坏的,给了一个 API 函数可以用来判定当前版本是否是坏的,让我们尽可能少的调用这个 API,找出第一个坏版本。那么这种搜索题最先开始考虑用二分查找法把,效率高嘛。由于这题很有规律,好版本和坏版本一定有个边界,那么用二分法来找这个边界,对 mid 值调用API函数,如果是坏版本,说明边界在左边,则把 mid 赋值给 right,如果是好版本,则说明边界在右边,则把 mid+1 赋给 left,最后返回 left 即可。需要注意的是,OJ 里有个坑,那就是如果 left 和 right 都特别大的话,那么 left+right 可能会溢出,这里处理方法就是变成 left + (right - left) / 2,很好的避免的溢出问题,参见代码如下:

 

// Forward declaration of isBadVersion API.
bool isBadVersion(int version);

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

 

如果习惯了二分搜索法从0开始找,可以用下面的方法:

 

// Forward declaration of isBadVersion API.
bool isBadVersion(int version);

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

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/278

 

参考资料:

https://leetcode.com/problems/first-bad-version/

https://leetcode.com/problems/first-bad-version/discuss/71311/A-good-warning-to-me-to-use-start%2B(end-start)2-to-avoid-overflow

 

LeetCode All in One 题目讲解汇总(持续更新中...)

posted @ 2015-09-08 02:30  Grandyang  阅读(10272)  评论(3编辑  收藏  举报
Fork me on GitHub