leetcode240——搜索二維矩陣(medium)

1、題目描述

編寫一個高效的算法來搜索 m x n 矩陣 matrix 中的一個目標值 target。該矩陣具備如下特性:python

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

示例:算法

現有矩陣 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。spa

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/search-a-2d-matrix-iicode

2、題解

方法一:暴力搜索法

方法一最容易想到,直接使用兩個for循環遍歷矩陣,當遇到與target相等的值時直接返回True便可。此法顯然不是出題人想要的結果。leetcode

完成時間:2020.05.07get

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

方法一使用了兩趟循環:io

時間複雜度:\(O(m * n)\)\(m\)指的是矩陣行數,\(n\)指的是矩陣列數。
空間複雜度:\(O(1)\)for循環

方法二:二分查找

方法二是對方法一的優化。因爲矩陣的行和列都已經排好序,那麼能夠利用二分查找加快目標值的查找速度。具體作法是當按行遍歷矩陣時,使用二分查找法對每行進行查找

注意:

  • 二分查找算法裏面有不少細節須要注意,否則極容易出錯。

完成時間: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)\)

相關文章
相關標籤/搜索