题目描述:
【简单题】
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
思路分析
1、由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。一带而发,因此可以用二分查找方法解决此题。
2、对中间值mid
调用 isBadVersion()
,如果返回False,则说明mid
左半部分的版本均未出错,则在其右半部分继续二分查找,否则在左半部分查找。
【python3代码实现】
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left=0
right=n
while left<right:
mid=left+(right-left)//2
if isBadVersion(mid):
right=mid
else:
left=mid+1
return left#或者right,因为终止条件是left==right
题目描述:
思路分析
-1 : 你猜测的数字比系统选出的数字大
1 : 你猜测的数字比系统选出的数字小
0 : 恭喜!你猜对了!
显然可以使用二分查找法。
# The guess API is already defined for you.
# @param num, your guess
# @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
# def guess(num: int) -> int:
class Solution:
def guessNumber(self, n: int) -> int:
left = 0
right = n
while left<=right:
mid=left+(right-left)//2
if guess(mid) == 0:
return mid
elif guess(mid)==1:
left=mid+1
else:
right=mid-1
另一种写法
# The guess API is already defined for you.
# @param num, your guess
# @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
# def guess(num: int) -> int:
class Solution(object):
def guessNumber(self, n):
left = 1
right = n
while left < right:
# mid = left + (right - left) // 2
mid = (left + right) >> 1
if guess(mid) == 1:
# 中位数比猜的数小,因此比中位数小的数包括中位数都不是目标元素
left = mid + 1
else:
right = mid
# 最后剩下的数一定是所求,无需后处理
return left
中位数的计算方法:
1、mid = (left + right) / 2
; 是初级写法,是有 bug 的:有可能会溢出。
2、 mid = left + (right - left) / 2
; 是正确的写法,考虑到了整型溢出的风险;
3、mid = (low + high) >> 1
; 右移运算符>>
,运算结果正好能对应一个整数的二分之一值,这就正好能代替数学上的除2运算,但是比除2运算要快。