前言
从今天起我会开启一个专栏:
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的次数
。
总结
以上就是我们
二分查找
在面试中的常见题型,一类是手写代码
,另一类是选择题
,在本文中均已讲到,最后,如果有什么错误的话,大家可以私信我📬📬,希望大家多多关注+点赞+收藏 ^_ ^🙏🙏,你们的鼓励是我不断前进的动力💪💪!!!