1. 程式人生 > >leetcode240——搜尋二維矩陣(medium)

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* ```python 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* ```python 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* ```python 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