一. 二分搜索(Binary Search)模板及其理解
1.通用模板,解决start, end, mid, <(<=), >(>=)等问题
http://www.lintcode.com/en/problem/binary-search/
class Solution { public: /** * @param nums: The integer array. * @param target: Target number to find. * @return: The first position of target. Position starts from 0. */ int binarySearch(vector<int> &array, int target) { // write your code here if(array.size() == 0){ return -1; } int start = 0, end = array.size() - 1; while(start + 1 < end){ int mid = start + (end - start) / 2; if(array[mid] == target){ end = mid; }else if(array[mid] < target){ start = mid; } else{ end = mid; } } if(array[start] == target){ return start; } if(array[end] == target){ return end; } return -1; } };
注意事项:
1). start + 1 < end (最后会剩下start, end两项);
2). mid = start + (end - start) / 2; (避免出现start + end越界情况);
3). A[mid] 依次比较 ==, <, >;
4). A[start], A[end]与target比较。 (对应first / last position问题,对应的比较顺序不用)
2. 对二分搜索的理解
1) 字面意义的二分搜索,对有序数组取中间值,比较并折半删除
2)first / last position问题,利用模板可以很好地解决
3)只有能判断解在某部分集合里,就可以将规模缩小(不一定是简单的在中间位置左侧或右侧),若每次规模近似缩小一半,仍然是二分的思路;
即将一个O(n)问题通过O(1)操作转化成一个O(k/2)的问题。
4)当复杂度要求O(logn)时,往往可以考虑二分搜索
二 常见问题
2.1 基础二分问题变种
1)Search a 2D matrix i
https://leetcode.com/problems/search-a-2d-matrix/
思路:将二维矩阵看做线性序列,则为典型二分搜索问题,所以只需要线性序列与二维数组小标的对应
即: mid / n , mid % n
class Solution { public: bool searchMatrix(vector<vector<int>>& matrix, int target) { int m = matrix.size(), n = matrix[0].size(); int start = 0, end = m*n - 1; while(start + 1 < end){ int mid = start + (end - start) / 2; if(matrix[mid/n][mid%n] == target){ return 1; } else if(matrix[mid/n][mid%n] < target){ start = mid; } else{ end = mid; } } if (matrix[start/n][start%n] == target) { return 1; } if (matrix[end/n][end%n] == target) { return 1; } return 0; } };