LeetCode第278题,第一个错误的版本,Java

目录

问题

思路

代码实现

效果


问题

思路:

        因为是排好序的数组,所以第一反应就是运用二分查找

        仍画一个表格进行分析,其中last 表示的是 最后一次看到的好版本

        例子1: n = 7, bad = 3

        因为在发现mid是坏的,跟last还差的很远的时候,我加入了一段代码,让last向后看,看看接着的一个是不是还是对的,如果是,那last进1,min进2进行判断,如下表:

        如果我的思路比较跳脱的话,没关系,建议先看我上一边关于二分法的笔记,然后再结合本题的代码实现,来进行理解,相信掌握了这个分析方法之后,所有的二分问题都会迎刃而解~

1234567
step1min,lastmidmax
step2lastmin,mid,max

         再举个栗子2: n = 5, bad = 3

        这种情况下,step1在找到mid是坏的,但是与last有距离

        同样道理,max—>mid-1=2;  检查last+1,发现还是好的,那last—>2,min—>3,这个时候进入下一轮循环是,max<min,跳出循环,return last+1 也就是3  就是正确答案

        为什么跳出循环的时候,输出last+1呢,因为在发现本身是正确的mid的时候没有范围,而是让其往前继续找,导致错过了正解,而同时,last也在积极向后看,征求与mid前边的数字回合,所以当跳出循环的时候,也就是last其实记录的是最后一个对的,,那再加一,就是第一个错的。

12345
step1min,lastmidmax
step2last,maxmin

代码实现:

/* 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 min = 1;
        int max = n;
        if(isBadVersion(min)){
            return min;
        }
        int last = 1;//用last表示上一个查找的错误的版本号
        
        while(min<=max){
            int mid = min + (max-min)/2;
            //判断mid版本是否是错误的
            if(isBadVersion(mid)){
                //如果是错误的,那看一下是不是第一个错误的版本,也就是判断是否与last挨着
                if(mid == last+1){
                    return mid;//如果挨着那就返回mid
                }else{
                    //如果 不紧挨着,那last和 mid之间,可能存在更早的错误版本;
                	//先判断last的下一个是不是错的,如果是,直接返回                	
                	if(isBadVersion(last+1)) {
                		return last+1;
                	}
                	//如果下一个还不是错的,那更新last和min;
                    last = last+1;
                    min =last+1;
                    max = mid - 1;
                }
                
            }else{
                last = mid;
                min = mid + 1;
            }
        }

        return last + 1;//如果找不到,说明last前的某一个值就是最后一个错的
    }
}

效果:

emmm,速度还可以,但是内存消耗较大,还有待改进~

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值