刷题网站:Leetcode
难度: 简单
语言: Python
计划:从简单——>到中等——>再到难。
一、278第一个错误版本
1.1 问题描述
假设版本开发中,错误的版本之后的所有版本都是错误的。有n
个版本[1,2,...,n]
,若想找出导致之后所有版本出错的第一个错误版本。
可以通过调用bool isBadVersion(version)
接口来判断版本号version
是否在单元测试中出错。实现一个函数来查找第一个错误的版本,应该尽量减少对调用API的次数。
- 示例1
输入:n=5,bad=4
输出:4
解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
- 示例2
输入:n = 1, bad = 1
输出:1
1.2 思考分析
刚开始,很容易误解题目意思,或者是没看懂题目。注意以下两点:
- 1)例如版本号
[1,2,3,...n]
用正错形式表示为[********######]
,其中*
表示正确的,#
表示错误的版本号,而题目要求的是第一次出现#
的位置。 - 2)
isBadVersion(3) -> false
这句的意思并不是单纯的根据false
理解它是错误,反而是结合isBadVersion()
判断是否为错误,若false
,双重否定等于肯定,则这句表示该版本是正确的,反之isBadVersion(4) -> ture
表示第4个版本号是错误的。
理解题意后,我们才好写出相应的代码。这题也是一种二分类方法,与前一篇704数组的二分查找类似。
1.3 解题过程
首先,控制台给出了初始代码,我们只需接着往后写即可。
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return an integer
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
此题已说定义了isBadVersion API
接口,我们就假设它是已经存在的,无需自己定义。因此,这题不能在pycharm中调试,只能在leetcode本地调试了。
- (1)首先,与之前方法不同,这里并不是用到下标索引,而是直接1到n的版本号,所以我们需要定义左端初始值为1
left=1
- (2)然后,我们需要有个循环,来判断是否是第一个错误出现的位置。注意循环成立的条件中不能写出
left<=n
,而应该写成left<n
。不然会陷入死循环,超出时间限制,即要保证至少有两个版本号。
while left<n:
- (3)最后,还需要在里面加个判断语句,来调用接口是否为
true
。最初,我还不了解如何调用isBadVersion() API
,直接模仿题目写
if isBadVersion() -> true:
\qquad 但是执行后,总是提示如下错误
扫描二维码关注公众号,回复:
14075140 查看本文章
SyntaxError: invalid syntax
\qquad 当我把->
改成常见的==
时,又如下错误
NameError:name'ture' is not defined
\qquad 后来,想了想isBadVersion()
是已经定义了的,应该不会有问题,那就是后面有问题了。再一想if
语句后面就是条件成立,再执行。因此,我干脆把后面去掉后,成功。
if isBadVersion():
- (4)最终的代码如下
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left = 1
while left<n:
mid = (n-left)//2 + left
if isBadVersion(mid):
n = mid
else:
left = mid + 1
return left
执行结果如下
击败了95.9%的用户,那本算法应该不算差的,其他可能每台电脑配置不一样,就导致的时间有出入。
1.4 总结
此题的重点是理解题意,刚开始看也没看懂,看评论才知道,调用API
接口的意思。算法思想还是二分查找法,与前一篇稍微有所差别,还是得多注意,多加练习。