最近在刷leetcode,发现很多题在刚开始看的时候思路很乱。用csdn来给自己做一个题解思路及难点的记录,方便自己复习的同时,也给大家提供一些思路。
题目:
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-bad-version
示例 1:
输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
示例 2:输入:n = 1, bad = 1
输出:1来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-bad-version
本题的输入有两个,第一个是版本个数n,第二个是第一个出错的版本编号,要求输出的也是第一个出错的版本编号。此题不严谨处在于可以通过硬编码来取得答案。本文将使用二分法的思想来解决这个问题。
代码中需要注意一下几点:
- 正溢出:因为版本数字可能非常大,所以有概率发生正溢出。解决方法:更换计算公式,避免大数字相加,c语言的话也可以给变量直接malloc内存。
- 移位优化:使用 >> 1 来替代 / / 2 可以加快计算
- 返回条件:由于while循环在不断缩小范围,当最后high和low相等时,我们就能得到第一个bad version。
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
low = 0
high = n
while low < high:
mid = low + (high - low >> 1)
guess = isBadVersion(mid)
if guess: # if the mid version is bad, means the first bad version is on the right, narrow the right boundary
high = mid # 不加一因为这个有可能是第一个bad version
else: # if the mid version is good, means the first bad version is on the right, narrow the left boundary
low = mid + 1 # true value不可能是第一个bad one
# When the low meets high, we get the first bad version
return high