题目
在一个二维数组中,每一行都按照从左到右递增的顺序,每一列都按照从上到下递增的顺序
排序。每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个
整数,判断数组中是否含有该整数。
例:
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
查找7,输出True;查找5,输出False
思路
- 从(0,0)开始搜索,采用深度优先搜索的策略,先往右,再往下,失败则返回上一级。此外,需要附加一个缓存,避免重复搜索。假设输入n*n的矩阵。
- 时间复杂度:O(n^2)
- 空间复杂度:缓存需要O(n)?还是O(logn)?
- 采用广度优先搜索的策略,每次搜索一斜层的元素,即(0,0); (0,1),(1,0) ; (0,2), (1,1) , (2,2)……
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
- 前两种算法,没有利用到该数组是排序数组的特点,因此再时间复杂度上过大。考虑到对于矩阵m*n有,(m,n) >= 其他元素,(0,0) <= 其他元素,可以先遍历对角上的元素,即可排除< 和 > 搜索元素的区域。再对剩下的区域递归。
- 时间复杂度:T(n) = 2T(n/4) + O(√n) = √nlogn
- 空间复杂度:递归深度O(logn)
- 思路3虽然利用了给定的排序条件,但是仍然不直观,代码比较复杂,需要递归。
根据书上的思路,查找从右上角(0,n-1)开始。对于(i,j),在正下方的都>该数字,在左侧的都<该数字。
因此,如果search < (i,j) 就向左查找,>(i,j)就向下查找。- 时间复杂度:只能向左向下移动,最多2n次。O(n)
- 空间复杂度:O(1)
代码
思路4:时间复杂度O(n),空间复杂度O(1)
def find_in_partially_sorted_matrix(nums, target):
"""
:param nums: the matrix
:param target: num for searching
:return: find or not or empty input
"""
if not nums or not nums[0]:
# empty input
return None
row = len(nums) - 1
col = len(nums[0]) - 1
i,j = 0, col
find = False
while i <= row and j >= 0:
if target == nums[i][j]:
find = True
break
elif target > nums[i][j]:
i += 1
else:
j -= 1
return find
思考
该题的主要突破点在于选择合适的划分方法,使得在划分元素的不同侧对应不同的取值范围。这样每一步都可以缩小范围并不会遗漏。