编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
比较好玩的一题,上来一下被吓到了,找不出规律。仔细一想遍历一遍查找O(nm),按行二分查找O(mlogn)。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
for (int[] row : matrix) {
int low = 0, high = row.length-1;
while (low <= high) {
int mid = (high - low) / 2 + low;
int num = row[mid];
if (num == target) {
return true;
} else if (num > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
}
return false;
}
}
看了题解,还真有规律,其实本质还是一种二分查找,只是比较值并不是中点,而是矩阵的右上角,为什么呢?
答案:
每次比较后都可以排除掉一行或者一列。
右上角元素是所在行的最大值:如果目标值大于右上角的元素,那么目标值肯定不在当前行,因此我们可以向下移动到下一行。
右上角元素是所在列的最小值:如果目标值小于右上角的元素,那么目标值肯定不在当前列,因此我们可以向左移动到前一列
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int x = 0, y = n - 1;
while (x < m && y >= 0) {
if (matrix[x][y] == target) {
return true;
}
if (matrix[x][y] > target) {
--y;
} else {
++x;
}
}
return false;
}
}
嘻嘻,其实选择左下角也有相同的性质,大家可以去试试哦!
class Solution(object):
def searchMatrix(self, matrix, target):
if not matrix or not matrix[0]:
return False
m, n = len(matrix), len(matrix[0])
x, y = m - 1, 0
while x >= 0 and y < n:
if matrix[x][y] == target:
return True
elif matrix[x][y] > target:
x -= 1
else:
y += 1
return False