二分法思路
有一个无序不重复的装满数字的列表,例如:
int[] arr = {1, 5, 3, 4, 2, 6, 7};
现在有一个需求,给定一个数字num,用二分法的方式查找出这个num所在的下标:
实现步骤
二分法,即将数组分割成两半,那么,我们肯定需要找到三个东西:
- 起始下标
- 中间数的下标
- 末尾下标
计算公式:中间数下标=(起始下标+末尾下标)/2
拿上面的例子来说,起始下标为0,末尾下标为arr.length-1(为啥减一,心里有点逼数)
那么中间下标就为3(打个比方,上面的例子)
中间下标找到了,那么对应的中间数也就找到了:arr[中间数下标]
我们就要去判断,输入的num和这个中间数谁大谁小,如果比中间数大,那么我们找这个数就只需要去考虑中间数右边的那一串数字,如果比中间数小,那么我们就去考虑左边的数字
假如我们需要找的数字在中间数的右边,那我们就只需要把数组的起始下标改成中间数往右移动一位。反之,在左边的话就把末尾下标往左启动一位。再不清楚,画个图就能清楚了:
我们用Java来实现:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// write your code here
int[] arr = {1, 7, 3, 4, 5, 6, 2};
Arrays.sort(arr);
System.out.println(binarySearch(arr, 6));
System.out.println(8 / 2);
}
/*
* 问题:
* 给定一个数组,无序不重复,要求给定任何一个数字,找到对应的索引,用二分法
* 思路:
* 定义两个下标分别是0和arrays.length-1(因为这个长度才是数组的长度)
* 定义一个中间数为数组长度的一半。判断输入的数大于或者小于这个中间值
* 如果大于中间值,那么起始位置就用中间值+1
* 如果小于中间值,那么末尾位置就用中间值-1
* */
public static int binarySearch(int[] arr, int value) {
//起始位置
int start = 0;
//结束位置
int end = arr.length - 1;
while (true) {
// 计算中间位置
int mid = (start + end) / 2;
if (value == arr[mid]) {
return mid;
}
if (value < arr[mid]) {
end = mid - 1;
}
if (value > arr[mid]) {
start = mid + 1;
}
if (start > end) {
return -1;
}
}
}
}