二分查找算法的实现以及解决整数溢出问题

前言

  从今天起我会开启一个专栏:Java面试八股文,记录一下我在网上学到的Java面试常考的一些内容,注意:本人暂无面试经验,只是在网上找视频学习到的❗❗❗

二分查找

  我们首先要学习的是二分查找,我相信很多人跟我一样,在看到这四个字的时候会想,这不是刚学Java的时候已经学习过了吗,但是本篇文章会告诉你面试的时候二分查找会出哪些题型,以及也会讲到我之前没有注意过的整数溢出的问题 💪💪。

  首先,什么是二分查找呢,顾名思义,肯定跟二分有关系,也可以叫它折半查找,存储结构采用的是有序数组,首先记录数组第一个元素的位置和数组最后一个元素的位置,然后相加除以2,找到中间元素的位置,然后和你需要查找的元素比较,如果比你要查找的元素小,那么记录第一个元素的位置不变,将记录最后一个元素的位置变为记录中间位置减一的位置,如果比你要查找的元素大,那么记录最后一个元素的位置不变,将记录第一个元素的位置变为记录中间元素位置加一的这个位置,然后继续相加除以2,以此类推,直到找到你想要查找的元素或者找完了找不到为止,因为它每次查找是舍去一半的,所以叫二分查找或者折半查找,接下来我们来看看代码如何实现的👇👇。

public class Main {
    public static void main(String[] args) {
        int [] a ={1,2,3,4,5,6,7,8,9};
        int target = 6;
        int index = binarySearch(a, target);
        System.out.println(index);
    }

    public static int binarySearch(int []a,int target){
        int l = 0,r = a.length-1,m;
        while(l <= r){
            m = (l+r)/2;
            if(a[m]==target){
                return m;
            }else if(a[m] > target){
                r = m -1;
            }else{
                l = m + 1;
            }
        }
        return -1;

    }
}

在这里插入图片描述

  那么到这里二分查找就完了吗,当然不是,如果到这里就完了的话,就跟我们之前学的就一样了,我们就没有讲的必要了,我们看代码的12行:m=(l+r)/2,m是int类型的,肯定是有范围的,如果l+r的值过于大,导致结果超过了int类型的最大范围,那么结果必然会出错,接下来我们就要解决这类问题👇👇。

二分查找解决整数溢出问题(方法1)

  首先我们先来演示一下整数溢出的情况,然后在再解决这个问题,我们在代码中定义数组的最后一个元素的位置为Integer.MAX_VALUE-1,那么如果它要查找的元素如果在数组的左半部分,则不会发生溢出现象,如果在数组的右半部分,则必然会发生溢出现象👇👇。

public class Main1 {
    public static void main(String[] args) {

        //1.模拟要找的值在中间值左侧
        int l = 0;
        int r = Integer.MAX_VALUE-1;
        int m =(l+r)/2;
        System.out.println(m);

        //模拟要找的值在中间值右侧,会溢出
        l = m+1;
        m = (l+r)/2;
        System.out.println(m);
    }
}

在这里插入图片描述

  在计算机中在进行基本运算时,是以二进制的方式进行计算的(逢二进一),而最高位代表的是符号位,也就是正负,0代表正,1代表负当数据过大会溢出时,会向符号位进一,就会改变运算的最终结果,如上图第二行数据☝️☝️。

  那我们的第一种解决办法就是通过改变数学表达式,达到在计算的过程中数值较小,不会发生溢出现象的效果:将(l+r)/2进行变换👇👇。

在这里插入图片描述

public class Main1 {
    public static void main(String[] args) {

        //1.模拟要找的值在中间值左侧
        int l = 0;
        int r = Integer.MAX_VALUE-1;
        int m =l+(r-l)/2;
        System.out.println(m);

        //模拟要找的值在中间值右侧
        l = m+1;
        m = l+(r-l)/2;
        System.out.println(m);
    }
}

在这里插入图片描述

二分查找解决整数溢出问题(方法2)

  方法二其实更高效一些,它是通过无符号的右移运算符:>>>代替掉除法运算的,它不光能解决我们的溢出问题,在效率上也是比除法高的👇👇。

public class Main1 {
    public static void main(String[] args) {

        //1.模拟要找的值在中间值左侧
        int l = 0;
        int r = Integer.MAX_VALUE-1;
        int m =(l+r)>>>1;
        System.out.println(m);

        //模拟要找的值在中间值右侧
        l = m+1;
        m = (l+r)>>>1;
        System.out.println(m);
    }
}

在这里插入图片描述

二分查找选择题目

  二分查找面试题一部分是让你手写二分查找代码,上边我们已经讲过,另一部分就是以选择题的形式出现👇👇。

在这里插入图片描述

答案:4次

在这里插入图片描述

答案:4次
注意:如果数组的元素为偶数个时,如果没有特别要求,我们通常选取中间靠左边的元素作为中间元素。

在这里插入图片描述

答案:七次
  解析:可以将上边的问题转化为:2^n=128,求n,或者让128一直除2,向下取整,直到剩下被除数为1为止,统计除以2的次数

总结

  以上就是我们二分查找在面试中的常见题型,一类是手写代码,另一类是选择题,在本文中均已讲到,最后,如果有什么错误的话,大家可以私信我📬📬,希望大家多多关注+点赞+收藏 ^_ ^🙏🙏,你们的鼓励是我不断前进的动力💪💪!!!

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

续写青春.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值