240. 搜索二维矩阵 II
剑指 Offer 04. 二维数组中的查找
题目
在一个 n m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
*示例:
现有矩阵 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
题解
首先的思路是,通过 [left,right]x[low,high] 确定一个搜索区域,先是
- 横向搜索,让right停在比target大的一列,然后
low++ - 竖向搜索,让high停在比target大的一行,然后
left++
重复1、2环节即可,其实可以通过二分法优化搜索过程,但实际上right和high的移动不太频繁,使用二分法速度反而比直接循环慢。
class Solution(object):
def findNumberIn2DArray(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
n = len(matrix)
if n == 0:
return False
m = len(matrix[0])
if m == 0:
return False
left, low = 0, 0
high = n-1
right = m-1
while left <= right and low <= high:
for j in range(right, left-1, -1):
if matrix[low][j] < target:
break
elif matrix[low][j] == target:
return True
right = min(j+1, m-1)
low += 1
if low > high:
break
for i in range(high, low-1, -1):
if matrix[i][left] < target:
break
elif matrix[i][left] == target:
return True
high = min(i+1, n-1)
left += 1
return False
执行用时:24 ms, 在所有 Python 提交中击败了81.64%的用户 内存消耗:17 MB, 在所有 Python 提交中击败了79.01%的用户
由于 high, right 是单调递减的,因此算法复杂度为 O(m+n)
解法2
从右上角出发:
- 一直往左走,停到刚好比target小的一个位置
- 然后再往下走一格
- 重复第1步

这个复杂度其实和上面的方法一样,都是 O(m+n) ,但理解和实现起来更简单。
class Solution(object):
def findNumberIn2DArray(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
n = len(matrix)
if n == 0:
return False
m = len(matrix[0])
if m == 0:
return False
i, j = 0, m-1
while i < n and j >= 0:
val = matrix[i][j]
print(val)
if val > target:
j -= 1
elif val == target:
return True
else:
i+=1
return False
