二分法起源于数学中找函数零点的问题:
对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。
解题思路:使用二分法查找的时候需注意该数组是有序的,一般为升序,所以使用二分法查找时先用快速排序法将其排序,这个方法较省时间。因此在刷题的时候注意给定的是否为有序数组或集合
时间复杂度:O(logn),其中 n 为数组的长度。二分查找所需的时间复杂度为 O(logn)。
空间复杂度:O(1)。我们只需要常数空间存放若干变量。
二分法查找注意点:区间问题。左闭右闭,还是左闭右开(一般语言默认),根据区间要注意代码循环的范围,是小于等于,还是小于,例如left<=right or left<=right, left=mid+1 or left=mid
具体情况都要根据题意来分析
常规二分查找法:
public int searchInsert(int[] nums, int target) {
int n = nums.length;
// 定义target在左闭右闭的区间,[low, high]
int low = 0;
int high = n - 1;
while (low <= high) { // 当low==high,区间[low, high]依然有效
int mid = low + (high - low) / 2; // 防止int溢出
if (nums[mid] > target) {
high = mid - 1; // target 在左区间,所以[low, mid - 1]
} else if (nums[mid] < target) {
low = mid + 1; // target 在右区间,所以[mid + 1, high]
} else {
// 1. 目标值等于数组中某一个元素 return mid;
return mid;
}
}
// 2.目标值在数组所有元素之前 3.目标值插入数组中 4.目标值在数组所有元素之后 return right + 1;
//因为存在一种情况是 target 大于数组中的所有数,此时需要插入到数组长度的位置。
return high + 1;
}
代码摘录代码随想录