LeetCode: 240. 搜索二维矩阵 II

129 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

240. 搜索二维矩阵 II

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/se…

编写一个高效的算法来搜索 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

示例 2: 输入: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 = 20 输出:false

提示:

  • m == matrix.length

  • n == matrix[i].length

  • 1 <= n, m <= 300

  • 109<=matrix[i][j]<=109-10^9 <= matrix[i][j] <= 10^9

  • 每行的所有元素从左到右升序排列

  • 每列的所有元素从上到下升序排列

  • 109<=target<=109-10^9 <= target <= 10^9

解法

  • 方法1-暴力遍历法

  • python

class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if matrix is None or len(matrix) < 1:
            return False
        rows = len(matrix)
        cols = len(matrix[0])
        # BF 算法 复杂度为O(mxn)
        for i in range(rows):
            for j in range(cols):
                if matrix[i][j] == target:
                    return True
        return False 
  • 方法2-二分查找法:每一行都是有序数组,对每一行使用二分查找法
class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if matrix is None or len(matrix) < 1:
            return False
        rows = len(matrix)
        cols = len(matrix[0])
        
        # 二分法
        def helper(orderList, target):
            n = len(orderList)
            left = 0
            right = n-1
            while left <= right:
                mid = left + (right-left)//2
                if orderList[mid] == target:
                    return True
                elif orderList[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            return False
        
        for i in range(rows):
            if (helper(matrix[i], target)):
                return True
        return False

第三种:规律观察法Z 字形查找: 每行每列最右边的元素是最大值。可以从矩阵matrix 的右上角 (0, n-1)(0,n−1) 进行搜索。在每一步的搜索过程中,如果我们位于位置 (x, y),那么我们希望在以 matrix 的左下角为左下角、以x,y) 为右上角的矩阵中进行搜索,即行的范围为 [x, m - 1],列的范围为 [0, y]:

class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if matrix is None or len(matrix) < 1:
            return False
        rows = len(matrix)
        cols = len(matrix[0])
       
        # 使用有序排列信息,每次与最右上角的元素进行比较,如果小于它,减少列,如果大于它,增加行
        i = 0
        j = cols-1
        while i < rows and j >= 0:
            if matrix[i][j] < target:
                i += 1
            elif matrix[i][j] > target:
                j -= 1
            else:
                return True
        return False

复杂度分析

  • 时间复杂度:O(mn), O(nlogm), O(m+n)
  • 空间复杂度:O(1), O(1), O(1)