三个例题教会你二分法


二分法?

先看一个很有意思的段子

有一天小明到图书馆借了 N 本书,出图书馆的时候,警报响了,于是保安把小明拦下,要检查一下哪本书没有登记出借。小明正准备把每一本书在报警器下过一下,以找出引发警报的书,但是保安露出不屑的眼神:你连二分查找都不会吗?于是保安把书分成两堆,让第一堆过一下报警器,报警器响;于是再把这堆书分成两堆…… 最终,检测了 logN 次之后,保安成功的找到了那本引起警报的书,露出了得意和嘲讽的笑容。于是小明背着剩下的书走了。 从此,图书馆丢了 N - 1 本书。

相信大家从小学的时候就已经接触过了很多关于二分法的题目了,对于二分法的一些思想这里博主就不展开说了

那么今天博主就从编程算法的角度来讨论,如果遇到二分法的题目该这么解答。

例题

首先我们要知道使用二分法是有一个条件的,那就是必须是顺序排序的,这个我们要注意。

 public static void main(String[] args) {
        int[] nums = {-1, 0, 3, 5, 9, 12};
        int target = 9;
        int n = 9;
        //调用如下方法
        
        //数组查找
        int i = search(nums,target);
        System.out.println(i+1);
        
        //错误版本号
       int j = search2(n);
       System.out.println("错误的版本号为:"+j);
       
        //输出插入位置
        int k = search3(nums, target);
        System.out.println("插入位置是"+(k+1));
    }

数组查找

给定一个数组和一个目标值,需要找到这个目标值在数组中的位置,并打印,如果没有则输出-1

    private static int search1(int[] nums, int target) {
//        定义数组的左右指针
        int left = 0, right = nums.length - 1;
//        判断条件:当左指针大于右指针的时候,我们默认循环结束
        while (left < right) {
//          定义一个数用接收二分法所选的位置 = 左指针位置+剩余长度的一半
            int mid = left + (right - left) / 2;
//           判断条件
            if (nums[mid] > target) {//如果所选的这个数大于目标值,那么目标值在它的左边
//                这个时候就需要调整右指针
                right = mid - 1;//需要注意数组下标越界
            } else if (nums[mid] < target) {//反之亦然
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return -2;
    }

错误版本号

你是产品经理,目前正在带领一个团队开发新的产品。假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

    private static int search2(int n) {
//        在这个代码中我们只需要定义一个左指针
            int left = 0;
//            判断条件依然是当左边界大于右边界时
            while (left < n) {
               int mid = left + (n - left) / 2;
//               在这个题中,给定的条件是需要判断是是否为该版本为错误版本
                if (isBadVersion(mid)) {
//                    所以我们可以直接将这个值赋值给n
                    n = mid;
                } else {
                    left = mid + 1;
                }
            }
            return n;
        }

插入位置

这个题和上面的数组位置中的位置查找有些不同的是,如果这个位置的值不存在那么就把这个位置的索引给返回。

  private static int search3(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        //最后返回的是他们的位置
        return left;
    }
   

好了详细就举这三道例题了,二分法的介绍就这样吧,后续博主还会出关于算法题目详解,喜欢的就留下三连吧,我们下片博客见。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远归的雁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值