leetcode No278 第一个错误的版本 java
Posted 短腿Cat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode No278 第一个错误的版本 java相关的知识,希望对你有一定的参考价值。
题目
题解
来看题,假如我是产品经理,那么我早就被打死了。。。(误
不逗了不逗了,本题要注意的就是isBadVersion(int i)这个函数是已经定义好供我们调用的,现在给了我们一个n,就是总版本数,当我们调用到正确版本的时候就返回false,当调用到错误版本的时候返回true,所以第一个错误版本的左边就全都是false,右边(包括第一个错误版本自己)就全都是true,下面我们使用0代表false,1代表true,则举例如下:
第一个“1”就是第一个错误版本,也就是我们要找到的位置,下面我们来说解法:
说实话我第一想法,这不就倒着推嘛,从n往前一个一个推,劈里啪啦一顿乱写,然后超时了。。。(我寻思你产品经理做了2126753390个版本???)
换一个思维,找到第一个1,它的特征如刚才我所述,左边全是0,右边全是1,那我们其实可以使用到二分法查找:
我们取左边第一个(下标为1)为left,最后一个(下标为n)为right,中间为mid。(mid = (right + left)/ 2)
-
下标为mid的值如果是1,说明结果是在左边范围的:
-
因此进行下一步:将mid作为right的新值,再在left和right中继续上述步骤,找到新的mid位置,这一次我们发现mid处为0,因此答案在mid右边儿:
因此,再更新的时候,我们进一步缩小范围,这里肯定有人会觉得那就是让left = mid了,不对哦,是left = mid + 1,原因我们稍后说,先一起往下看,操作之后情况如下:
此时,其实mid值已经来到了result值了,但是我们还是继续按照上面的步骤走,mid值等于1,因此让right值等于mid,再看下一步:
最终left与right走到了一起,如果继续往下,mid、left、right都不会再发生改变,因此找出答案!答案的判断点儿在于left == right
下面我们来看两个细节问题:
-
为什么让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上的) -
如何求解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. 第一个错误的版本(First Bad Version)