菜雞每日一題系列打卡74天
每天一道算法題目
小夥伴們一起留言打卡
堅持就是勝利,我們一起努力!
題目描述(引自LeetCode)
編寫一個高效的算法來判斷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
題目分析
這明顯是一道二分法的題目。我們可以採用兩種思路來實現:一種是先對行進行二分,找到target可能在的行,然後再對列進行二分,判斷target是否存在。另一種是對所有的數當作一維有序數組進行二分,然後映射到二維數組的對應座標中。
Talk is cheap,菜雞將採用上述兩種方法進行實現。話不多說,上代碼!
代碼實現
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
// 特殊情況處理
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
int rowStart = 0, rowEnd = matrix.length - 1, rowMid = 0;
int colStart = 0, colEnd = matrix[0].length - 1;
// 二分法尋找行
while (rowStart <= rowEnd) {
rowMid = rowStart + ((rowEnd - rowStart) >> 1);
if (matrix[rowMid][0] == target) return true;
else if (matrix[rowMid][0] > target) rowEnd = rowMid - 1;
else if (matrix[rowMid][colEnd] < target) rowStart = rowMid + 1;
else break;
}
// 二分法尋找列
while (colStart <= colEnd) {
int colMid = colStart + ((colEnd - colStart) >> 1);
if (matrix[rowMid][colMid] == target) return true;
else if (matrix[rowMid][colMid] > target) colEnd = colMid - 1;
else colStart = colMid + 1;
}
return false;
}
}
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
// 特殊情況處理
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
int m = matrix.length;
int n = matrix[0].length;
// 二分法
int start = 0, end = m * n - 1;
while (start <= end) {
// 按照一維數組來計算中間座標
int mid = start + ((end - start) >> 1);
// 定位中間座標所在行
int row = mid / n;
// 定位中間座標所在列
int column = mid % n;
// 比較判斷
if (matrix[row][column] == target) return true;
else if (matrix[row][column] > target) end = mid - 1;
else start = mid + 1;
}
return false;
}
}
代碼分析
對代碼進行分析,第一種實現方式,對行和列分別進行二分,時間複雜度爲O(max(logm, logn)),空間複雜度爲O(1);第二種實現方式,對所有數字進行二分,然後映射到具體的二維數組座標,時間複雜度爲O(log(mn)),空間複雜度爲O(1)。
乍一看,覺得第一種實現方式的時間複雜度好像更低一些,其實只要稍加分析,對於第二種實現方式,log(mn) = logm + logn,就會發現,這只是個數學遊戲而已,兩種實現方式的時間複雜度並無本質區別。
執行結果
對行和列分別進行二分的執行結果
對所有數字進行二分然後進行下標映射的執行結果
學習 | 工作 | 分享
????長按關注“有理想的菜雞”
只有你想不到,沒有你學不到