在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
来源:力扣(LeetCode) 剑指offer 04
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof
示例:
现有矩阵 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。
给定 target = 20,返回 false。
限制:
0 <= n <= 1000
0 <= m <= 1000
解题思路
观察发现,任意一个不在第一行和最后一列的数,其上面的数比他小,右边的数比它大,类似于二叉搜索树。因此我们可以从左下节点开始,依次判断该节点的值和目标值target的大小关系,若比target大,则说明target在节点上方,节点往上走,反之则在右边,节点往右走,直到超出边界停止。
复杂度
- 时间复杂度:
O(n+m)
, 最多遍历n+m
次 - 空间复杂度:O(1),常数复杂度,指针使用常数额外空间
代码实现
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
i , j = len(matrix) - 1 , 0
while i >= 0 and j <= len(matrix[0]) - 1: #注意到了边界还有再判断一次
if matrix[i][j] > target:
i -= 1
elif matrix[i][j] < target:
j += 1
else:
return True
return False
总结
这道题主要在于发现该数组和二叉搜索树的相似之处,可以把数组逆时针旋转90度看。
补充
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
另外贴上我的博客Victor’s Blog,推荐pc访问,手机端还没失配好。