二分查找法的前提就是针对于有序的序列,基于分治的思想,提高查询的效率。
参考:https://zh.wikipedia.org/wiki/二分搜索算法
迭代实现:
public static int binarySearch(int[] arr, int aim) {
if (arr == null || arr.length == 0) return -1;
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int m = (left + right) / 2;
int v = arr[m];
if (v == aim) return m;
else if (v < aim) {
// 因为 v < aim,则可以排除掉 arr[m],因此只要在 [m+1, right] 的范围内找
// 如果不多位移一位(即 m+1),则最后就会因 left == right 陷入死循环
// 对于递归的实现也是如此
left = m + 1;
} else {
right = m - 1;
}
}
return -1;
}
需要注意的是代码中的注释部分。
public static int binarySearch2(int[] arr, int aim) {
if (arr == null || arr.length == 0) return -1;
return digui(arr, aim, 0, arr.length - 1);
}
public static int digui(int[] arr, int aim, int left, int right) {
if (left > right) return -1;
int m = (left + right) / 2;
int v = arr[m];
if (v == aim) {
return m;
} else if (v < aim) {
return digui(arr, aim, m + 1, right);
} else {
return digui(arr, aim, left, m - 1);
}
}
时间复杂度
折半搜索每次把搜索区域减少一半,时间复杂度为 O(log n)
。(n代表集合中元素的个数)
空间复杂度
O(1)
。虽以递归形式定义,但是为尾递归,可改写为循环。