要求
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
思路
方法一:暴力查找
遍历整个矩阵matrix,判断target是否出现即可
public boolean searchMatrix(int[][] matrix, int target) {
for (int[] row : matrix) {
for (int element : row) {
if (element == target) {
return true;
}
}
}
return false;
}
看不懂上面的写法的话,看下面这种
public boolean searchMatrix(int[][] matrix, int target) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == target){
return true;
}
}
}
return false;
}
方法二:二分查找法
看到有序,第一反应就是二分查找。一行一行的进行二分查找即可。
public boolean searchMatrix(int[][] matrix, int target) {
for (int i = 0; i < matrix.length; i++) {
int l = 0, r = matrix[0].length - 1;
while (l < r){
int mid = l + r + 1 >> 1;
if (matrix[i][mid] <= target){
l = mid;
}else {
r = mid - 1;
}
}
if (matrix[i][l] == target){
return true;
}
}
return false;
}
时间复杂度:O(m∗logn)
空间复杂度:O(1)
方法三:
数组从左到右和从上到下都是升序的,如果从右上角出发开始遍历,会发现每次都是向左数字会变小,向下数字会变大;所以我们可以把 target 和当前值比较:
- 如果 target 的值大于当前值,那么就向下走。可以把当前列去掉,从新的右上角的值开始遍历。
- 如果 target 的值小于当前值,那么就向左走。
如果相等的话,直接返回 true 。
public class LeetCode240 {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix.length == 0 || matrix[0].length == 0){
return false;
}
//定义矩阵中第一行的最后一位元素,就是右上角元素
int row = 0,col = matrix[0].length - 1;
while (row < matrix.length && col >= 0){
//如果目标元素大于右上角元素,则删除行,目标元素小于右上角元素,则删除列;要不就是目标元素返回true
if (target > matrix[row][col]){
row++;
}else if (target < matrix[row][col]){
col--;
}else {
return true;
}
}
return false;
}
}
时间复杂度:O(m + n)
空间复杂度:O(1)