题目介绍
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例: 在下图矩阵中,查找数字7。
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
题目解读
矩阵每行从左到右递增,每列也从上到下递增,因此右下方的数字一定大于当前位置的数字,左下方的数字一定小于当前位置的数字。 我们可以利用这个规律去查找目标数字。
算法解析
按行二分查找
思路是按行判断数字是否在此行:
- 如果数字小于此行的第一个数字(最小),证明矩阵里没有这个数,返回False;
- 如果大于此行的最后一个数字,证明不在此行,可能在下一行;
- 如果处于这行范围内,进行二分查找。
时间复杂度为二分查找O(logn)。
class Solution:
# array 二维列表
def binarySearch(self, nums, target):
start = 0
end = len(nums)-1
while start <= end:
mid = (start + end)//2
if nums[mid] == target:
return True
elif nums[mid] > target:
end = mid - 1
else:
start = mid + 1
return False
def Find(self, target, array):
# write code here
if not array or not array[0]:
return False
row = len(array)
col = len(array[0])
for i in range(row):
if target > array[i][-1]:
continue
if target < array[i][0]:
break
if self.binarySearch(array[i], target):
return True
else:
continue
return False
行列查找
这个是剑指上面的思路。
结合实例来进行说明:
原矩阵如下,target为7:
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
从右上角开始看,9大于7,且9是这列的最小数,因此不可能在最后一列,缩小搜索范围:
1 2 8
2 4 9
4 7 10
6 8 11
同理,也不再8开头这一列,缩小为:
1 2
2 4
4 7
6 8
开头数字为2,转换为行查找,第一行最大为2,因此排除此行,缩小为:
2 4
4 7
6 8
同理,排除第二行:
4 7
6 8
最后在第三行检索得到7。
时间复杂度为O(n)。
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if not array or not array[0]:
return False
row = len(array)
col = len(array[0])
i = 0
j = col - 1
while i < row and j >= 0:
if array[i][j] == target:
return True
elif array[i][j] > target:
j -= 1
else:
i += 1
return False