衆所周知,對於面試而言,《劍指offer》是一本「好書」。面試
若是你和我同樣是個算法菜雞,那麼最推薦的是先把劍指offer的題目搞明白,其次再去刷LeetCode等習題,這樣對於面試突擊很是有用,由於面試官最常考的算法題都在這本書裏。算法
若是你發現看這本書很吃力,能夠先直接參考些網上的代碼,照着抄一遍,理解下算法題是應該解題,多抄幾道題目,你就對算法題的作法有感受了,這個高考作固定套路數學題是同樣的。編程
對於劍指offer題解這個系列,個人寫做思路是,對於看過文章的讀者,可以作到:後端
你能夠經過如下幾種途徑查看個人《劍指offer題解》系列:數組
在一個二維數組中(每一個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。安全
首先可以想到的確定是一行一行或者一列一列遍歷,判斷數組中是否含有該整數。該方法顯然是最笨拙的二維數組遍歷,面試官也不會滿意,時間複雜度是O(n^2)微信
class Solution: def Find(self, target, array): for i in range(len(array)): for j in range(len(array[0])): if array[i][j]==target: return True return False
咱們思考下,既然大的數字都在靠右邊/下邊,可否能利用行列的數據變化規律來優化下解法,若是尋找的目標數大於如今的數字,那麼目標數字是在當前位置的右邊或下邊,若是所尋找的目標數小於如今的數字,那麼目標數字在當前位置的左邊或上邊。舉個例子,以下圖數組所示:ide
1 2 3 4 2 3 8 9 3 4 9 10 4 5 10 11
咱們的位置是1,要找8,8大於1,那麼在1的右邊和下邊區域進行下一步的搜索。函數
若是咱們先搜索他的右邊,測試
2 3 4 3 8 9 4 9 10 5 10 11
又搜索了他們的下邊,
2 3 8 9 3 4 9 10 4 5 10 11
這時候咱們發現
3 8 9 4 9 10 5 10 11
這個區域搜索了兩次,咱們是從數組的第一個數[0][0]取的,遇到了重複搜索區域的問題。有沒有方法去除重複的搜索區域呢,咱們發現,當從右上角取第一個數的時候,能夠去除重複的搜索區域,仍是以這個數組爲例,取4,搜索8,發現8比4大,那麼8不可能出如今4這一行,只須要從下邊搜索便可。若是尋找3,3比4小,4那一列後續的數都大於4,只須要從左邊搜索便可。
1 2 3 4 2 3 8 9 3 4 9 10 4 5 10 11
咱們還能夠發現左下角的點也能夠去除重複搜索區域,總結起來的話,有點像變量控制法的感受,將一個變量控制住,根據另一個變量的規律,得出結論。
這樣咱們將時間複雜度降爲了O(n)
public class Solution { public boolean Find(int target, int [][] array) { int rows = array.length; int cols = array[0].length; int i = rows-1, j = 0; while(i >= 0 && j < cols){ if(target < array[i][j]) i--; else if(target > array[i][j]) j++; else return true; } return false; } }
class Solution: def Find(self, target, array): if array == ([] or [[]]): return False row = len(array) col = len(array[0]) i=0 j=col-1 while 0<=i<row and 0<=j<col: if target>array[i][j]: i=i+1 elif target<array[i][j]: j=j-1 else: return True return False
題目簡單,小夥伴們須要理解的是算法題應該注重的是效率優化,暴力窮舉可以解決問題,但說服不了面試官。
你能夠經過如下兩種途徑查看《劍指offer題解》系列:
我是一名後端開發工程師。
主要關注後端開發,數據安全,爬蟲,物聯網,邊緣計算等方向,歡迎交流。
公衆號:後端技術漫談.jpg
若是文章對你有幫助,不妨收藏,投幣,轉發,在看起來~