Write an efficient algorithm that searches for a value in an m x n
matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Example 1:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 Output: true
Example 2:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 Output: false
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
看完题目大概猜到要用到二分查找法,但是题目要求从一个矩阵查找目标数,那关键点就变成如何查找中间点来把矩阵分成两区间。仔细分析题目就会发现这题跟LeetCode 704. Binary Search一样就是一道最基础的二分查找法的题。
题目说到矩阵里的数是有序的,每一行的数都是排好序的从左到右递增,后一行的第一个数比前一行的最后一个数大。我们会发现这个顺序跟我们平常遍历矩阵的顺序是一样的,即从左到右从上到下遍历。因此如果我们按从左到右从上到下遍历矩阵把矩阵转换成一个一维数组,那这个数组就是一个排好序的递增数组,并且数组的下标又跟矩阵的行列下标有一一对应的关系。
本题就变成了从一个排好序的一维数组里查找一个目标数, 跟LeetCode 704. Binary Search一模一样。
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
m, n = len(matrix), len(matrix[0])
l, r = 0, m * n - 1
while l <= r :
mid = l + (r - l) // 2
i, j = mid // n, mid % n
if matrix[i][j] == target:
return True
if matrix[i][j] < target:
l = mid + 1
else:
r = mid - 1
return False