提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
对于二分查找:
Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky.
一、二分查找的框架
int binarySearch(int[] nums, int target) {
int left = 0, right = ...;
while(...) {
int mid = (right + left) / 2;
if (nums[mid] == target) {
...
} else if (nums[mid] < target) {
left = ...
} else if (nums[mid] > target) {
right = ...
}
}
return ...;
}
分析二分查找的一个技巧是:不要出现 else,而是把所有情况用 else if 写清楚,这样可以清楚地展现所有细节。其中…标记的部分,就是可能出现细节问题的地方,当见到一个二分查找的代码时,首先注意这几个地方。
二、寻找一个数(基本的二分搜索)
搜索一个数,如果存在,返回其索引,否则返回 -1。
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right) {
int mid = (right + left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return -1;
}
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
三、寻找左侧边界的二分搜索
代码如下:
int left_bound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0;
int right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
return left;
}
四、寻找右侧边界的二分查找
代码如下:
int right_bound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0, right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
left = mid + 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
return left - 1;
总结
-
分析二分查找代码时,不要出现 else,全部展开成 else if 方便理解。
-
注意「搜索区间」和 while 的终止条件,如果存在漏掉的元素,记得在最后检查。
-
如需要搜索左右边界,只要在 nums[mid] == target 时做修改即可。搜索右侧时需要减一。