Binary Search
Binary Search的题目我之前一直搞不清楚,一写就错,现在好了一些,总结下模版。
模版分成两种:
一、寻找某个指定的值,比如问数组中是否存在这个target,或者这个target的index是多少,对于这一种有三种模版:
1.lo <= hi
while (lo <= hi) {
int mid = (hi - lo) / 2 + lo;
if (mid == target) return true;
if (mid < target) lo = mid + 1;
else hi = mid - 1;
}
return false;
2.lo + 1 < hi
while (lo + 1 < hi) {
int mid = (hi - lo) / 2 + lo;
if (mid == target) return true;
if (mid < target) lo = mid;
else hi = mid;
}
return false;
3.lo < hi
while (lo < hi) {
int mid = (hi - lo) / 2 + lo;
if (mid == target) return true;
if (mid < target) lo = mid + 1;
else hi = mid;
}
return false;
二、不是寻找某一特定的值,而是找满足某条件的第一个值(有些题目虽然没有直接问第一个满足某条件的值,但可以转换成这种形式)。这种情况下上面的第三个模版最方便。
Java中自带的Arrays.binarySearch(nums, target)可以找到target在该数组中应该插入的位置,等价于寻找第一个大于等于该数的位置
int lo = 0, hi = nums.length;
while (lo < hi) {
int mid = (hi - lo) / 2 + lo;
if (nums[mid] >= target)
hi = mid;
else lo = mid + 1;
}
return lo;
经典的题目有:
4. Median of Two Sorted Arrays
33. Search in Rotated Sorted Array
81. Search in Rotated Sorted Array II
153. Find Minimum in Rotated Sorted Array
154. Find Minimum in Rotated Sorted Array II
在二维数组中binary search
74. Search a 2D Matrix(线性)
240. Search a 2D Matrix II(非线性)
binary search比较少见的应用(LIS问题)
300. Longest Increasing Subsequence
354. Russian Doll Envelopes
binary search在有些情况下可以替代hashmap的功能,在数组中查找某个数是否存在,当然前提条件是该数组已经排好序。binary search更多的用于替代Treemap的ceiling和floor功能,查找大于等于(大于)/小于等于(小于)某个数的最小/最大值。
binary search的另一种用法,以值作为搜索条件,比如某数组虽然没有排序,但知道数组元素的取值范围,这个时候就可以将取值范围作为binary search的搜索范围
378. Kth Smallest Element in a Sorted Matrix
287. Find the Duplicate Number(有快慢指针法)
410. Split Array Largest Sum(有dp解法)
如果题目是在一个二维矩阵中找到某个或某些满足条件的矩形,我们可以先考虑如果相同的条件放在一维数组里面怎么做,然后把二维矩阵降维成一维数组进行处理。下面的代码是二维降一维:
int m = matrix.length, n = matrix[0].length;
for (int l = 0; l < n; l ++) {
int[] sums = new int[m];
for (int r = l; r < n; r ++) {
for (int i = 0; i < m; i ++)
sums[i] += matrix[i][r];
......
// 有了sums数组之后就可以用一维的方法处理了
}
}
这种类型的题目有:
363.Max Sum of Rectangle No Larger Than K
1074.Number of Submatrices That Sum to Target
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。