剑指Offer 4.二维数组中的查找(Python)

题目介绍

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例: 在下图矩阵中,查找数字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

你可能感兴趣的:(剑指Offer)