题目
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
思路
方法一:二分法
遍历行/列,然后再对列/行进行二分(如,遍历每一行,然后对每一行的内容,即按照列进行二分查找)
相当于就是二分查找外面套了一个for
循环,二分查找返回目标值target
的索引
java代码如下:
class Solution {
public boolean searchMatrix(int[][] matrix, int target){
for(int[] row : matrix){
int index = binarySearch(row,target);
if(index >= 0){
return true;
}
}
return false;
}
public int binarySearch(int[] nums, int target){
int l = 0, r = nums.length -1;
while(l <= r){
int mid = l + (r - l) / 2;
int num = nums[mid];
if(num == target){
return mid;
} else if (num > target){
r = mid - 1;
} else {
l = mid + 1;
}
}
return -1;
}
}
方法二:抽象BST
将二维矩阵抽象成「以右上角为根的 BST
」:
红色表示右子树,橙色表示左子树
可以从根节点(右上角)开始搜索,如果当前节点不等于目标值,可以按照树的搜索顺序进行:
- 当前节点大于目标值的话,搜索当前节点的左子树,也就是当前矩阵位置的左方格子,即
col--
- 当前节点小于目标值的话,搜索当前节点的右子树,也就是当前矩阵位置的下方格子,即
row++
java代码如下:
class Solution{
public boolean searchMatrix(int[][] matrix, int target){
int m = matrix.length;//行数
int n = matrix[0].length;//列数
int r = 0,c = n - 1;//因为是从右上角的点(0,n-1)开始,即第0行第n-1列
while(r < m && c >= 0){//因为行是从0 ~ m-1 行,列是从0 到 n-1 列
if(matrix[r][c] < target){
r++;//小于目标值则找下方格子
} else if (matrix[r][c] > target){
c--;//大于目标值则找左方格子
} else return true;
}
return false;
}
}