来源:快手面试题
题目:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析:
1 2 3
4 5 6
7 8 9
因为从左到右递增,从上到下递增。 我们观察这个数组可发现
左上是最小的值 右下是最大的值
左下从列到行(14 7 89)为一个递增序列
右上从行到列(12 3 69)为一个递增序列
思考①
左下从列到行(14 7 89)为一个递增序列
我们初始化 i=2,j=0(左下) 对比元素 temp=7时, 一列上都比其小,一行左都比其大
当 目标元素 target > 7 则不用考虑比7小的(不用考虑该列) j = j+1 =1
当 目标元素 target < 7 则不用考虑比7大的(不用考虑该行) i = i-1 =1
当 目标元素 target = 7 时,直接返回 True
相当于从左下角开始 不断的往右上缩减矩形的过程,
思考②
右上从行到列(12 3 69)为一个递增序列
我们初始化 i=0,j=2(右上) 对比元素 temp=3时, 一行左都比其小,一列下都比其大
当 目标元素 target > 3 则不用考虑比3小的(不用考虑该行) i = i+1 =1
当 目标元素 target < 3 则不用考虑比3大的(不用考虑该列) j = j-1 =1
当 目标元素 target = 3 时,直接返回 True
相当于从右上角开始 不断的往左下缩减矩形的过程,
复杂度: 时间复杂度 O(M+N) 空间复杂度 O(1)
PS:找有序
代码:
def findNumberIn2DArray(matrix, target):
# matrix 为 []时,直接返回False
if len(matrix) == 0:
return False
n, m = len(matrix), len(matrix[0])
i, j = 0, m - 1
while i < n and j >= 0:
if matrix[i][j] == target:
return True
elif matrix[i][j] > target:
j = j - 1
else:
i = i + 1
return False
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 = 0
print(findNumberIn2DArray(matrix, target))