目录
题目描述
在一个 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的题解:
如示例
(1)缩小行数范围
第 0 列,如果target < 10, 表示10之后的所有数都比target大, 由第0列找出上限m_max
第n-1列,如果target > 19, 表示19之前的所有数都比target小,由第n-1列找出下限m_min
则所要找的数在(m_min, m_max)中的行里面
(2)缩小列数范围
第 0 行,如果target < 15, 表示15之后的所有数都比target大, 由第0行找出上限n_max
第m-1行,如果target > 18, 表示18之前的所有数都比target小,由第m-1行找出下限n_min
则要找的数在(n_min, n_max)中的列里面可以将两者配合使用,不断缩小查找范围
依次查找这些行中是否有target
注意:确定行数范围以及查找target过程中均采用二分查找
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
# 二分查找
def binary(nums, left, right, target):
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else: # nums[mid] == target:
return True, left # 表示找到了target
return False, left # 表示没找到terget
# matrix 为空
if len(matrix) == 0 or len(matrix[0]) == 0:
return False
# 小于最小值,大于最大值,直接排除
m = len(matrix) # 行数
n = len(matrix[0]) # 列数
if target < matrix[0][0] or target > matrix[m - 1][n - 1]:
return False
# 缩小行数范围
nums1 = [matrix[i][0] for i in range(0, m)]
nums2 = [matrix[i][n - 1] for i in range(0, m)]
tag1, m_max = binary(nums1, 0, m - 1, target)
tag2, m_min = binary(nums2, 0, m - 1, target)
if tag1 or tag2: # 首列或者最后一列就有这个数
return True
# 缩小列数范围
nums3 = matrix[m_min]
nums4 = matrix[m_max - 1]
tag3, n_max = binary(nums3, 0, n - 1, target)
tag4, n_min = binary(nums4, 0, n - 1, target)
if tag3 or tag4:
return True
# 按行查找
for i in range(m_min, m_max): # 注意 左闭右开
tag, left = binary(matrix[i], n_min, n_max - 1, target)
if tag:
return True
return False
【最优题解】:
特性: 一个数的左面和上面的数均小于该数; 一个数的右面和下面的数均大于该数;
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
if len(matrix) == 0 or len(matrix[0]) == 0:
return False
m = len(matrix)
n = len(matrix[0])
i = 0
j = n - 1
while i < m and j >= 0:
if target > matrix[i][j]:
i += 1
elif target < matrix[i][j]:
j -= 1
else:
return True
return False