题目:
编写一个高效的算法来搜索 m x n 矩阵中的一个目标值。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
例如,
考虑下面的矩阵:
[ [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
。
给定目标值 target = 20
, 返回 false
。
解法1:时间复杂度O(m+n)
思路:从最后一行第一列开始检索,比目标值大则从上一行继续检索,比目标值大则从下一列继续检索。直到超出范围。
def searchMatrix( matrix, target): if matrix: row,col,width=len(matrix)-1,0,len(matrix[0]) while row>=0 and col< if matrix[row][col]==target: return True elif matrix[row][col]>target: row=row-1 else: col=col+1 return False
解法2:分治法
思路:
分:矩阵最中间的数【row//2,col//2】与目标值对比大小,矩阵分为四块(大于、小于和两块不确定)。如题中矩阵,中间数为matrix【2,2】=9,红色部分都小于等于9,黑色部分都大于等于9,黄色和蓝色部分不确定。
【[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]】
治:
子问题五种:矩阵大小为0时,矩阵大小为1*1,矩阵大小为1*2,矩阵大小为2*1,矩阵大小为2*2
【原因是矩阵大小小于2*2时,【row//2,col//2】=【1,1】,会造成死循环。】
只要目标值不在矩阵中就返回False,只要有就返回True。
并:不需要
代码:
def searchMatrix(matrix, target): #矩阵大小为0的情况 if len(matrix)==0: return False elif len(matrix[0])==0: return False row=len(matrix) col=len(matrix[0]) i=row//2 j=col//2 matrix_new=[] matrix_new1=[] matrix_new2=[]
#矩阵大小为1*1 if row==1 and col==1: if target==matrix[0][0]: return True else: return False
#矩阵大小为2*1 elif row==2 and col==1: if matrix[0][0]==target: return True elif matrix[1][0]==target: return True else: return False
#矩阵大小为1*2 elif row==1 and col==2: if matrix[0][0]==target: return True elif matrix[0][1]==target: return True else: return False
#矩阵大小为2*2 elif row==2 and col==2:if matrix[0][0]==target: return True elif matrix[0][1]==target: return True elif matrix[1][0]==target: return True elif matrix[1][1]==target: return True else: return False
#矩阵大小大于2*2时 else:
#矩阵分块的右上角即蓝色部分,flag1是继续递归判断目标值在不在蓝色这里 for item in matrix[:i]: matrix_new1.append(item[j+1:])
flag1=searchMatrix(matrix_new1, target)
#矩阵分块的左下角即黄色部分,flag2是继续递归判断目标值在不在黄色这里
for item in matrix[i+1:]: matrix_new2.append(item[:j]) flag2=searchMatrix(matrix_new2, target) if target==matrix[i][j]: return True
#中间值比目标值大,则在左上角或者两个不确定的那两块。 elif target<matrix[i][j]: for item in matrix[:i+1]: matrix_new.append(item[:j+1]) flag3=searchMatrix(matrix_new, target) flag=flag3 or flag1 or flag2 return flag
#中间值比目标值小,则在右下角或两个不确定那两块。 else: for item in matrix[i:]: matrix_new.append(item[j:]) flag3=searchMatrix(matrix_new, target) flag=flag3 or flag1 or flag2 return flag if __name__=='__main__': matrix=[[1,3,5]] target=5 print(searchMatrix(matrix, target))