1. 程式人生 > >leetcode的python實現 刷題筆記74:搜尋二維矩陣(二分查詢的思想)

leetcode的python實現 刷題筆記74:搜尋二維矩陣(二分查詢的思想)

編寫一個高效的演算法來判斷 m x n 矩陣中,是否存在一個目標值。該矩陣具有如下特性:

  • 每行中的整數從左到右按升序排列。
  • 每行的第一個整數大於前一行的最後一個整數。

示例 1:

輸入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
輸出: true

示例 2:

輸入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
輸出:
false
class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        # 首先判斷二維陣列的行數和列數是否為0,也就是判斷這個二維陣列是否為空陣列
        if len(matrix) == 0 or len(matrix[0]) == 0:
            return False
        # 定義行數和列數
        hang = len(matrix)
        lie = len(matrix[0])
        # 按照下標來判斷每個數字在陣列中的位置,arr【0】【0】的下標為0。arr【hang】【lie】的下標是hang * lie - 1
        start, end = 0, hang * lie - 1
        '''以下判斷的是行數列數大於1的情況'''
        # 使用while迴圈來遍歷二維陣列,使用二分查詢的思想,先找到中間值,然後判斷中間值和target的大小.
        # mid // lie表示的是中間值的行座標,mid % lie表示的是中間值的列座標
        '''
        如果中間值=target,返回true
        如果中間值>target,根據有序陣列可知,target有可能出現在start到mid之間,因此將end變成mid,繼續二分查詢
        如果中間值<target,根據有序陣列可知,target有可能出現在mid到end之間,因此將start變成mid,繼續二分查詢
        '''
        while start + 1 < end:
            mid = start + (end - start) // 2
            if matrix[mid // lie][mid % lie] > target:
                end = mid
            elif matrix[mid // lie][mid % lie] < target:
                start = mid
            else:
                return True
        '''以下判斷的是行數大於1,列數等於1的情況'''
        if matrix[start // lie][start % lie] == target:
            return True
        '''以下判斷的是列數大於1,行數等於1的情況'''
        if matrix[end // lie][end % lie] == target:
            return True
        # 凡是不滿足以上的條件就返回false
        return False


sl = Solution()
print(sl.searchMatrix( [[1,   3,  5,  7],[10, 11, 16, 20],[23, 30, 34, 50]], 5))
print(sl.searchMatrix( [[1,   3,  5,  7]], 7))
print(sl.searchMatrix( [[1],[9],[23]], 9))

思路:

1.首先判斷下進來的陣列是否為空陣列,如果是就返回false

2.接下來分三種情況:行數列數都大於1,行數大於1列數等於1,行數等於1列數大於1.然後就使用二分查詢的方法來查詢

3.找到首值和尾值的下標,例如在例子中,1的下標是0,3的下標是1,5的下標是2,7的下標是3,依次類推

4.找到中間值,判斷中間值與target的大小。

如果中間值=target,返回true
如果中間值>target,根據有序陣列可知,target有可能出現在start到mid之間,因此將end變成mid,繼續二分查詢
如果中間值<target,根據有序陣列可知,target有可能出現在mid到end之間,因此將start變成mid,繼續二分查詢

5.以上的情況都不符合的話就說明不存在

總結:

1.mid = start + (end - start) // 2      為了防止溢位

2.二維陣列的下標表示

3.以及如何找到想要的元素的下標,例如mid // lie表示的是中間值的行座標,mid % lie表示的是中間值的列座標