【力扣 leetcode】278题 第一个错误的版本firstBadVersion 二分查找入门 java数据结构

力扣 278题 第一个错误的版本

上一篇两数相加的博客收获了我的第一个点赞和评论!动力满满嗷现在!
我属于是纯纯的算法菜狗,有任何错误和意见还请朋友们在评论区告诉我!
在这里插入图片描述

好的废话不多说,先上题目和代码。

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int low =1;
        int high =n;
        while(low<=high){
            int mid = low+(high-low)/2;
            if(isBadVersion(mid)==true&&isBadVersion(mid-1)==false){
                return mid;
            }
            else if(isBadVersion(mid)==true){
                high = mid - 1;
            }
            else{
                low = mid + 1;
            }
        }
        return -1;
}
}

这道题是非常标准的二分查找题,先设置好高低两个指针,分别指向头和尾。

int low =1;
int high =n;

然后进入while循环,开始二分查找。大家不妨记住下面这段伪代码(默认数组从小到大排序),典型二分查找的构造,都是差不多滴 ~ ~ ~

 while(low<=high){
			 int mid = low+(high-low)/2;//中间指针mid
			 if( mid==目标值)
			 		return mid;
			 else if(mid >目标值)
			 		high = mid -1; //如果数组按照从大到小排序则相反。
			  else if(mid <目标值)
			 		low = mid + 1; //如果数组按照从大到小排序则相反。
			 }

二分查找每一次查找就三个结果

  1. 找到了,返回索引。
  2. 大了,目标值在mid左边,high就变成mid - 1.
  3. 小了,目标值在mid右边,low就变成mid + 1.

三种结果对应了伪代码中的三个分支,这样就很好理解了对不对!继续下一次查找之前要把mid值更新一次。
回到这道题,找到第一个错误版本也就是说,首先这个版本要是错的,其次前一个版本是对的,所以正确的条件显而易见了!

 if(isBadVersion(mid)==true&&isBadVersion(mid-1)==false){
                return mid;
            }

最后如果始终没找到错误版本,在循环结束之后返回 -1,大功告成。
在这里插入图片描述
在这里插入图片描述
做完之后看了官方的题解,感觉自己对二分查找的理解还差了不少意思,这里附上官方的题解代码。

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1, right = n;
        while (left < right) { // 循环直至区间左右端点相同
            int mid = left + (right - left) / 2; // 防止计算时溢出
            if (isBadVersion(mid)) {
                right = mid; // 答案在区间 [left, mid] 中
            } else {
                left = mid + 1; // 答案在区间 [mid+1, right] 中
            }
        }
        // 此时有 left == right,区间缩为一个点,即为答案
        return left;
    }
}

好了那这道题的分享就结束了!如果有任何建议请在评论区留下你的足迹!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值