看似简单的二分查找,但是实际写起来的时候就不是那么回事了。也在校招的机器学习岗位面试上被问到了,没有无误的写出,被直接赶走。
看编程珠玑,也是说,在Bell实验室,规定时间内,很多工程师写不全对。也曾看到有人感叹,做了6年的程序员,面试时被一道冒泡排序卡住。感觉算法和数据结构作为一个工程师的基本技能是必须要加强的。
下面直接列代码,需注意的是,在计算middle的值的时候,我们需要更换上下界。但是如果直接将上下界换位middle的时候,对第一个字符是能找到的,因为我们进行除二,取到的int值是偏向左边的。但是如果是找最后一个字符,就会出现找不到的现象,条件不达标而一直循环。
所以,在写该代码的时候,需要注意替换上届的时候,middle - 1;替换下届的时候,middle + 1。
package basic;
public class BinarySearch {
public static void main(String[] args) {
BinarySearch search = new BinarySearch();
int[] arrays = new int[]{1, 2, 3, 4, 5};
int value = 3;
System.out.println(search.binarySearch1(arrays, value));
// System.out.println(search.binarySearch2(arrays, 0, 4, value));
}
/**
* 非迭代写法
* @param arrays
* @param value
* @return
*/
public int binarySearch1(int[] arrays, int value) {
int left = 0;
int right = arrays.length;
while(left < right) {
int middle = (left + right) / 2;
int midValue = arrays[middle];
if(value > midValue) {
left = middle + 1;
System.out.println("大于,左边界变更为" + arrays[left]);
}
else if(value < midValue) {
right = middle - 1;
System.out.println("小于,右边界变更为" + arrays[right]);
}
else{
System.out.println("正好在中间" + middle);
return middle;
}
}
return -1;
}
/**
* 迭代写法
* @param arrays
* @param left
* @param right
* @param value
* @return
*/
public int binarySearch2(int[] arrays, int left, int right, int value) {
if(left > right) {
return -1;
}
int middle = (left + right) / 2;
int midValue = arrays[middle];
if(value < midValue) {
return binarySearch2(arrays, left - 1, middle, value);
}
else if(value > midValue) {
return binarySearch2(arrays, middle + 1, right, value);
}
else {
return middle;
}
}
}