前言:
社长,4年api搬运工程师,之前做的都是一些框架的搬运工作,做的时间越长,越发感觉自己技术越菜,有同感的社友,可以在下方留言。现更侧重于java底层学习和算法结构学习,希望自己能改变这种现状。
为什么大厂面试,更侧重于java原理底层的提问,因为通过底层的提问,他能看出一个人的学习能力,看看这个人的可培养潜力。随着springboot的流行,大部分的开发,起步就是springboot。也不看看springboot为什么简单?他底层是如何实现的。为什么同样出来4年,工资差别都很大?这些问题都值得我们深思(对社长自己说的)。
api工程师,顶天了,最多达到某些公司中级工资上限,很难突破高级这道坎。希望我们大家成就更好的自己。回想起往事,不会后悔。
目录
一 什么是二分法查找?
二分法也可以叫折半法,他是一种一种查询效率较高的方法。适用于数据量较大时,但是需要数据先排好顺序。
小结:遇到效率高,我们就应该引起注意,就跟ArrayList一样,他的查询效率高,但是只适合于单线程,因为他线程不安全。遇到类似的问题,我们应该多反问(社长的一万个为什么),多思考。多想想,他是不是有什么缺陷或者前提。
二 实现思路
一个班的成绩有高有低,从低到高排序 50 56 60 70 80 90 92 94 98
因为是二分,每次取一般,这里先定义三个变量header mid footer,注意是对应值的下标。
分三种情况:
第一种: 相等,表示找到了。
我要找的值就是80。Mid对应的值,刚好与我要查的值相等。就没有必要继续往下走。
第二种:需要查找的值小于mid,footer=mid-1
划重点上一次的mid是4,值为80,为什么上面画的图没有80?
在第一种情况里面已经判断过,那我们为什么还需要再判断一次勒,你们说是不是这个道理。觉得对的社友扣666。
有些有着求知欲的社友,又开始问了,header为,footer为3,mid咋是1,不应该是1.5吗?
社长我也不知道为什么是1。(0+3)/2 就是1。可以先去查看一下基础。
第三种:需要查找的值大于mid,header=mid+1
学习中遇到问题后,我们应该如何处理?
我发现有不少社友都继承了社长的一万个为什么,首先,积极提出问题,这点值得表扬。社长工作也有一段时间了,遇到问题,发现,大致的人群可以分为3种。
按王者荣耀的术语做一个级别划分
第一种,不敢请教别人,怕暴露自己的真实水平,同事之间,遇到不少这种,建议,有可能你一个问题,卡了几天,别人给你一分钟指导,就帮你解决了。 青铜选手
第二种,敢于请教,但不思。 遇到问题,需要虚心的请教别人,但是,自己不多思,多查。 白银选手
第三种:多思多查敢于请教。 黄金选手
二分法查找2种实现方式
非递归方式
package com.fyqd.test.sort;
/**
* Description:不使用递归方式
* Author: 程序猿学社
* Date: 2020/1/18 21:38
* Modified By:
*/
public class BinaryTest {
public static int binary(int[] array, int value) {
int low = 0;
int high = array.length - 1;
while (low <= high) {
int middle = (low + high) / 2;
if (value == array[middle]) {
return middle;
}
if (value > array[middle]) {
low = middle + 1;
}
if (value < array[middle]) {
high = middle - 1;
}
}
return -1;
}
public static void main(String[] args) {
//50 56 60 70 80 90 92 94 98
int[] a = {50, 56, 60, 70, 80, 90, 92, 94, 98};
int score = 60;
int value = binary(a,score);
if(value == -1){
System.out.println("没有找到,继续加油!");
}else{
System.out.println("找到了你真棒,分数为"+score+",索引为"+value);
}
}
}
递归方式
package com.fyqd.test.sort;
/**
* Description:使用递归方式
* Author: 程序猿学社
* Date: 2020/1/18 21:38
* Modified By:
*/
public class BinaryTest1 {
public static int binary(int[] array, int value) {
int header = 0;
int footer = array.length - 1;
return search(array,value,header,footer);
}
public static int search(int[] array, int value,int header,int footer){
if(header > footer){
return -1;
}
int middle = (header + footer) / 2;
if (value == array[middle]) {
return middle;
}else if (value > array[middle]) {
header = middle + 1;
return search(array,value,header,footer);
}else{
footer = footer - 1;
return search(array,value,header,footer);
}
};
public static void main(String[] args) {
//50 56 60 70 80 90 92 94 98
int[] a = {50, 56, 60, 70, 80, 90, 92, 94, 98};
int score = 980;
int value = binary(a,score);
if(value == -1){
System.out.println("没有找到,继续加油!");
}else{
System.out.println("找到了你真棒,分数为"+score+",索引为"+value);
}
}
}
注意:使用递归方式,一定要给出终止条件
性能对比分析:
名称 | 时间复杂度 | 空间复杂度 | 描述 |
---|---|---|---|
普通排序 | O(N) | O(1) | 通过for循环一个个查找 |
二分法非递归方式 | O(logN) | O(1) | |
二分法使用递归方式 | O(logN) | O(1*logN) | 每次调用开销1,重复调用logN次,每次需要额外的开辟空间 |
二分法非递归方式性能最优,为什么
历史算法文章推荐:
博主,java小白,有问题欢迎在下方留言。大家互相交流,互相进步!
每周更新,分享各个技术点面试、结构和算法、源码分析等干货