leetcode No278 第一个错误的版本 java

Posted 短腿Cat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode No278 第一个错误的版本 java相关的知识,希望对你有一定的参考价值。

题目


题解

来看题,假如我是产品经理,那么我早就被打死了。。。(误

不逗了不逗了,本题要注意的就是isBadVersion(int i)这个函数是已经定义好供我们调用的,现在给了我们一个n,就是总版本数,当我们调用到正确版本的时候就返回false,当调用到错误版本的时候返回true,所以第一个错误版本的左边就全都是false,右边(包括第一个错误版本自己)就全都是true,下面我们使用0代表false,1代表true,则举例如下:

举例1
第一个“1”就是第一个错误版本,也就是我们要找到的位置,下面我们来说解法:

说实话我第一想法,这不就倒着推嘛,从n往前一个一个推,劈里啪啦一顿乱写,然后超时了。。。(我寻思你产品经理做了2126753390个版本???)
换一个思维,找到第一个1,它的特征如刚才我所述,左边全是0,右边全是1,那我们其实可以使用到二分法查找:
我们取左边第一个(下标为1)为left,最后一个(下标为n)为right,中间为mid。(mid = (right + left)/ 2)

  • 下标为mid的值如果是1,说明结果是在左边范围的:
    描述1

  • 因此进行下一步:将mid作为right的新值,再在left和right中继续上述步骤,找到新的mid位置,这一次我们发现mid处为0,因此答案在mid右边儿:
    描述2
    因此,再更新的时候,我们进一步缩小范围,这里肯定有人会觉得那就是让left = mid了,不对哦,是left = mid + 1,原因我们稍后说,先一起往下看,操作之后情况如下:
    描述3
    此时,其实mid值已经来到了result值了,但是我们还是继续按照上面的步骤走,mid值等于1,因此让right值等于mid,再看下一步:

描述4
最终left与right走到了一起,如果继续往下,mid、left、right都不会再发生改变,因此找出答案!答案的判断点儿在于left == right

下面我们来看两个细节问题:

  1. 为什么让right = mid,而left = mid + 1?
    答案的判别是让right == left,如果left 不等于mid + 1的话,最终会出现什么结果呢?我画图给大家看看:
    如果让left 移动到mid,则情况如下:
    在这里插入图片描述
    再因为mid值为1,因此right = mid 如下:
    在这里插入图片描述
    这里就是问题所在了,这种情况下,mid等于1,right等于mid,循环之后仍然是这样没变化,进入了死循环,因此这种情况出不了结果。如果让left = mid + 1 而不是 left = mid,这样不仅不会影响结果而且还能得出答案(因为让left移动的情况下只有可能是当前mid为0,即使mid + 1为结果1,结果最终也是会移动到这个结果1上的)

  2. 如何求解mid的值?
    这个看似麻瓜的问题确实绊倒我的一颗石头,我们寻思着mid不就按照如上所说的mid = (left + right) / 2 吗?错!
    假如right等于最大整型值,而left又是大于0的,那left + right 不就超出了吗?因此我们换一种思路,假设现在情况如下:
    在这里插入图片描述
    则求mid的方法可以通过这种思路:
    在这里插入图片描述
    通过绿色这一段left的长度加上红色这一段长度就可以了,而红色这一段长度刚好等于(right - left) / 2,这样就不会超出了。

代码如下:

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1;
        int right = n;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (isBadVersion(mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

这次简单题也被绊倒了两次,所以说做题还是得好好注意呀,尤其是整型超出这一部分,如果有用到某种数据类型(如int、byte这些)最大值或是最小值,一定要条件反射的思考到超出问题,可谁知这道题的产品经理这么牛逼,能把版本做到超出int范围呢[doge]
在这里插入图片描述
今日份题解已送达,客观还满意吗(昨天考6级鸽了一次题解,害)

以上是关于leetcode No278 第一个错误的版本 java的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 278. 第一个错误的版本

LeetCode 278. 第一个错误的版本(First Bad Version)

[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278

leetcode 278. 第一个错误的版本

Leetcode刷题Python278. 第一个错误的版本

LeetCode 278. 第一个错误的版本