LeetCode 75 —— 278. 第一个错误的版本

107 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

LeetCode 75 —— 278. 第一个错误的版本

一、题目描述:

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 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 <= bad <= n <= 2^31 - 1

来源:力扣(LeetCode) 链接:leetcode.cn/problems/fi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    这道题目是二分查找的实际应用题目,因为要尽可能的减少对API的调用,所以我们不能遍历所有版本来判断版本是否在单元测试中出错。此处我们需要将版本号的起始范围设置为left,终止范围设置为right。范围中心设置为mid,只要left小于right,我们就判断mid是否是BadVersion。如果mid是BadVersion,我们就可以确定其及其后全部是BadVersion,就可以将right赋值为mid,此时right还是BadVersion,如果mid不是BadVersion,就可以证明mid之前包括mid全部不是BadVersion,我们要求的是第一个BadVersion,所以可以将left设置为mid+1。一直到left与right相等。最后面的return返回left和right都行。

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    不是一次通过的,刚开始思路不清晰,没有处理好right、left以及for循环中left与right的关系,导致结果有些偏差。

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    这是一道典型的二分查找方法,Go语言中有个好玩的API,我们来看一看!

    func firstBadVersion(n int) int {
        return sort.Search(n, func(version int) bool { return isBadVersion(version) })
    }
    ​
    作者:LeetCode-Solution
    链接:https://leetcode.cn/problems/first-bad-version/solution/di-yi-ge-cuo-wu-de-ban-ben-by-leetcode-s-pf8h/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    index := sort.Search(n int,f func(i int) bool) int:该函数使用二分查找的方法,会从[0, n)中取出一个值index,index为[0, n)中最小的使函数f(index)为True的值,并且f(index+1)也为True。如果无法找到该index值,则该方法为返回n。

三、AC 代码:

/** 
 * Forward declaration of isBadVersion API.
 * @param   version   your guess about first bad version
 * @return            true if current version is bad 
 *                    false if current version is good
 * func isBadVersion(version int) bool;
 */
​
func firstBadVersion(n int) int {
    var left,right int
    left,right = 1, n
​
    for left < right{
        mid := (right-left)/2+left
        if isBadVersion(mid){
            right = mid
        }else{
            left = mid + 1 
        }
    } 
    return left
}
​

四、总结:

时间复杂度为O(log n),空间复杂度为O(1)。要吐槽一下,什么程序的版本会有2的31次方-1个...

模板来源:

作者:掘金酱

链接:juejin.cn/post/706970…

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。