LeetCode 278. First Bad Version
2016-04-07 22:27
507 查看
题目
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.
分析
我们先从二分查找说起. 一个简单的二分查找示例是从一个一维数组中查找某个数字x, 若存在, 返回其下标; 若不存在, 返回非法下标
-1.
代码如下:
int binsearch(int nums[], int len, int target) { int lo = 0, hi = len, mid; while (lo < hi) { mid = lo + ((hi - lo) >> 1); if (nums[mid] == target) { return mid; } else if (nums[mid] > target) { hi = mid; } else { lo = mid + 1; } } return -1; }
如果你经常忘记
while内的判定条件, 或者
hi和
lo的改变方式, 那么下面的分析或许可以帮到你. 初始时, 我们要查找的
x可能存在于
[lo, hi)限定的数组范围内. 这是一个左闭右开区间, 即
x可能是
nums[lo], 但绝不可能是
nums[hi]. 正应如此,
while中的条件应该是
lo < hi, 若不满足条件说明
x不在数组内. 循环内每次计算
mid, 然后对比
nums[mid]与
target, 若相同, 则返回
mid; 若
nums[mid]较大, 则
target只可能在
[lo, mid)中, 因此令
hi = mid; 否则,
target只能在
(lo, hi), 即
[lo+1, hi]中, 因此令
lo = mid + 1.
在此过程中,
lo始终为可能的最小下标,
hi始终比可能的最大下标大1.
将本题与上面的分析类比, 不难得出以下代码. 需要注意的是, 这里的所谓找到数字, 就是找到某一
mid使其满足以下两条件之一:
isBadVersion(mid)为
true, 而
isBadVersion(mid-1)为
false
isBadVersion(mid)为
true且
mid == 1
// Forward declaration of isBadVersion API. bool isBadVersion(int version); class Solution { public: int firstBadVersion(int n) { int lo = 1, hi = n+1; while (lo < hi) { int mid = lo + ((hi - lo) >> 2); if (isBadVersion(mid)) { if (mid == 1 || !isBadVersion(mid - 1)) { return mid; } else { hi = mid; } } else { lo = mid + 1; } } cout << "Won't be here" << endl; return -1; } };
然而提交后的结果是:
错误的原因是以
2147483647作为输入,
hi = n + 1导致结果超出
int所能表示的最大正整数, 因此在
while第一次测试条件时就跳过了循环. 我们对代码进行修正, 让
hi指向可能的 最大下标, 因此
while中条件判断也要作出修改, 因为此时
lo == hi也可能得出满足条件的
mid.
解答
// Forward declaration of isBadVersion API. bool isBadVersion(int version); class Solution { public: int firstBadVersion(int n) { int lo = 1, hi = n; while (lo <= hi) { // 注意! int mid = lo + ((hi - lo) >> 2); if (isBadVersion(mid)) { if (mid == 1 || !isBadVersion(mid - 1)) { return mid; } else { hi = mid; } } else { lo = mid + 1; } } cout << "Won't be here" << endl; return -1; } };
相关文章推荐
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解