编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
方法一:
分析:因为矩阵的行和列是排序的(分别从左到右和从上到下),所以在查看任何特定值时,我们可以修剪O(m)O(m)或O(n)O(n)元素。
算法:
首先,我们初始化一个指向矩阵左下角的 (row,col)(row,col) 指针。然后,直到找到目标并返回 true(或者指针指向矩阵维度之外的 (row,col)(row,col) 为止,我们执行以下操作:如果当前指向的值大于目标值,则可以 “向上” 移动一行。 否则,如果当前指向的值小于目标值,则可以移动一列。不难理解为什么这样做永远不会删减正确的答案;因为行是从左到右排序的,所以我们知道当前值右侧的每个值都较大。 因此,如果当前值已经大于目标值,我们知道它右边的每个值会比较大。也可以对列进行非常类似的论证,因此这种搜索方式将始终在矩阵中找到目标(如果存在)。
def search_matrix(matrix, target):
# 判断空矩阵
if len(matrix) == 0 or len(matrix[0]) == 0:
return False
height = len(matrix)
width = len(matrix[0])
# 从矩阵的左下角开始
row = height-1
col = 0
while col < width and row >= 0:
if matrix[row][col] > target:
row -= 1
elif matrix[row][col] < target:
col += 1
else:
return True
return False
时间复杂度:O(n+m)
空间复杂度:O(1)
方法二(二分法):
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
for i in range(len(matrix)):
if matrix[i][0] <= target <= matrix[i][len(matrix[i])-1]:
res = self.find_target(matrix[i], target)
if res:
return True
else:
pass
return False
def find_target(self, target_list: list, taget_number: int):
if len(target_list) == 1:
if target_list[0] == taget_number:
return True
else:
return False
elif len(target_list) > 1:
mid_number_index = len(target_list) // 2
if target_list[mid_number_index] == taget_number:
return True
elif target_list[mid_number_index] > taget_number:
return self.find_target(target_list[:mid_number_index], taget_number)
else:
return self.find_target(target_list[mid_number_index+1:-1], taget_number)
else:
return False