轉載本文章請標明作者和出處
本文出自《Darwin的程序空間》
本文題目和部分解題思路來源自《劍指offer》第二版
題目
在一個 n * m 的二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數;
-
示例
現有矩陣 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;
-
限制
0 <= n <= 1000
0 <= m <= 1000
解題分析
這道題最簡單的做法,就是暴力遍歷法,遍歷整個二位數組的元素,然後找到目標值並且返回,這樣的時間複雜度爲O(m*n);且沒有用到二維數組每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序的條件;
我們首先想到的就是可能從左上角的元素開始遍歷,這樣做有一個最大的問題,如果當前的元素比目標元素要小,那麼就有兩種走法,你往下走也會變大,往右走也會變大,這樣就有兩個選擇,就迫使你隨機選擇一個,如果選錯了,回頭就很難了;
但是如果我們換一個思路,從右上角或者左下角開始走的話,情景將會發生很大的轉變;右上角已經是最大的列了,如果目標值還比當前元素大隻有往下走一條路,如果比當前元素小,你也只有往左走一條路,從左下角開始也同理,直到找出界,那麼就是不存在目標整數,這樣的時間複雜度爲O(m+n);
-
題外話
這道題其實也蘊含了一個哲理,選一條對的路,一直走的頭就是答案,給自己太多的選擇,終究會找不到回去的路;
代碼
ps:這裏筆者使用的jdk爲1.8、python3.7
-
java實現(從右上角開始)
class Solution { public boolean findNumberIn2DArray(int[][] matrix, int target) { if (Objects.isNull(matrix) || matrix.length == 0 || matrix[0].length == 0) { return false; } int line = 0; int row = matrix[0].length - 1; while (true) { if (row < 0 || line >= matrix.length ) { return false; } else if (matrix[line][row] == target) { return true; } else if (matrix[line][row] > target) { row--; } else { line++; } } } }
-
python實現(從左下角開始)
class Solution: def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool: if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0: return False line, row = len(matrix) - 1, 0 while True: if line < 0 or row > len(matrix[0]) - 1: return False elif matrix[line][row] == target: return True elif matrix[line][row] > target: line -= 1 else: row += 1