搜索二维矩阵

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。

示例1

输入: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

方法一:
分析:因为矩阵的行和列是排序的(分别从左到右和从上到下),所以在查看任何特定值时,我们可以修剪O(m)O(m)或O(n)O(n)元素。

算法:
首先,我们初始化一个指向矩阵左下角的 (row,col)(row,col) 指针。然后,直到找到目标并返回 true(或者指针指向矩阵维度之外的 (row,col)(row,col) 为止,我们执行以下操作:如果当前指向的值大于目标值,则可以 “向上” 移动一行。 否则,如果当前指向的值小于目标值,则可以移动一列。不难理解为什么这样做永远不会删减正确的答案;因为行是从左到右排序的,所以我们知道当前值右侧的每个值都较大。 因此,如果当前值已经大于目标值,我们知道它右边的每个值会比较大。也可以对列进行非常类似的论证,因此这种搜索方式将始终在矩阵中找到目标(如果存在)。

def search_matrix(matrix, target):
    # 判断空矩阵
    if len(matrix) == 0 or len(matrix[0]) == 0:
        return False
        
    height = len(matrix)
    width = len(matrix[0])

    # 从矩阵的左下角开始
    row = height-1
    col = 0

    while col < width and row >= 0:
        if matrix[row][col] > target:
            row -= 1
        elif matrix[row][col] < target:
            col += 1
        else: 
            return True
    
    return False

时间复杂度:O(n+m)
空间复杂度:O(1)

方法二(二分法):

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        for i in range(len(matrix)):
            if matrix[i][0] <= target <= matrix[i][len(matrix[i])-1]:
                res = self.find_target(matrix[i], target)
                if res:
                    return True
            else:
                pass
        return False
    
    def find_target(self, target_list: list, taget_number: int):
        if len(target_list) == 1:
            if target_list[0] == taget_number:
                return True
            else:
                return False
        elif len(target_list) > 1:
            mid_number_index = len(target_list) // 2
            if target_list[mid_number_index] == taget_number:
                return True
            elif target_list[mid_number_index] > taget_number:
                return self.find_target(target_list[:mid_number_index], taget_number)
            else:
                return self.find_target(target_list[mid_number_index+1:-1], taget_number)
        else:
            return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值