zoukankan      html  css  js  c++  java
  • leetcode240——搜索二维矩阵(medium)

    一、题目描述

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

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

    示例:

    现有矩阵 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。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii

    二、题解

    方法一:暴力搜索法

    方法一最容易想到,直接使用两个for循环遍历矩阵,当遇到与target相等的值时直接返回True即可。此法显然不是出题人想要的结果。

    完成时间:2020.05.07

    class Solution:
        def searchMatrix(self, matrix, target):
            """
            :type matrix: List[List[int]]
            :type target: int
            :rtype: bool
            """
            for i in range(len(matrix)):
                for j in range(len(matrix[0])):
                    if matrix[i][j] == target:
                        return True
            return False
    

    方法一使用了两趟循环:

    时间复杂度:(O(m * n))(m)指的是矩阵行数,(n)指的是矩阵列数。
    空间复杂度:(O(1))

    方法二:二分查找

    方法二是对方法一的优化。由于矩阵的行和列都已经排好序,那么可以利用二分查找加快目标值的查找速度。具体做法是当按行遍历矩阵时,使用二分查找法对每行进行查找

    注意:

    • 二分查找算法里面有很多细节需要注意,不然极容易出错。

    完成时间:2020.05.09

    class Solution:
        def searchMatrix(self, matrix, target):
            """
            :type matrix: List[List[int]]
            :type target: int
            :rtype: bool
            """
            # 矩阵为空,直接返回False
            if not matrix:
                return False
            
            rows = len(matrix)
            columns = len(matrix[0])
    
            for i in range(rows):
                left = 0
                right = columns - 1 # 注意 
                while left <= right: # 注意要带等号,不然当数组只有一个值时,可能会漏掉结果
                    mid = (left + right) // 2
                    if matrix[i][mid] > target:
                        right = mid - 1
                    elif matrix[i][mid] == target:
                        return True
                    elif matrix[i][mid] < target:
                        left = mid + 1
            return False
    

    方法二使用了两趟循环:

    时间复杂度:for循环的时间复杂度为(O(m))(m)指的是矩阵行数,while循环的时间复杂度为 (O(log_{2}n)),n为矩阵的列数,所以总的时间复杂度为(O(m*log_{2}n));

    空间复杂度:(O(1))

    方法三:利用本题矩阵的特点

    既然题目告诉我们矩阵每行的元素从左到右升序排列,每列的元素从上到下升序排列,那么我们可以利用这一特性来巧妙解题。

    • 首先设置变量row表示行标,col表示列标,将row的初始值设为0,表示第一行,将col的初始值设为矩阵最后一列的下标;
    • 然后使用一个while循环遍历矩阵,若matrix[row][col] > target成立时,说明当前值比目标值target大,列标col需要左移来找到更小的值与target相比较;若matrix[row][col] < target成立时,说明当前值比目标值target小,行标row需要下移来找到更大的值与target相比较;若matrix[row][col] == target成立时,说明找到了目标值target,直接返回True即可;
    • 最后,若遍历结束仍然没有找到目标值target,说明矩阵中不存在目标值taregt,返回False即可。

    注意:

    • 与目标值比较的初始值选取的位置必须在矩阵的左下角和右上角处

    完成时间:2020.05.07

    class Solution:
        def searchMatrix(self, matrix, target):
            """
            :type matrix: List[List[int]]
            :type target: int
            :rtype: bool
            """
            if not matrix:
                return False
            
            row, col = 0, len(matrix[0]) - 1
            while row < len(matrix) and col >= 0:
                if matrix[row][col] > target:
                    col -= 1
                elif matrix[row][col] < target:
                    row += 1
                else:
                    return True
            return False
    

    方法三使用了一趟循环:

    时间复杂度:(O(m + n))(m)指的是矩阵行数,(n)指的是矩阵列数。row的最大值不超过矩阵行数m,col的最大值不超过矩阵列数n。
    空间复杂度:(O(1))

  • 相关阅读:
    设置 linux 下 firefox 的默认启动路径
    uvm读书笔记
    case不能复现,vcs 版本号不同带来的影响
    uvm override
    Jenkins 不执行构建里的命令
    sv 报语法错误
    linux 定时删除文件夹的的内容 (find && crontab 使用)
    学习:教材的本质
    学习的本质:认知深度
    演讲:给新仔讲过的商业内容
  • 原文地址:https://www.cnblogs.com/victorxiao/p/12860556.html
Copyright © 2011-2022 走看看