【劍指offer題解】二維數組中的查找

【劍指offer題解】二維數組中的查找

前言

衆所周知,對於面試而言,《劍指offer》是一本「好書」。面試

若是你和我同樣是個算法菜雞,那麼最推薦的是先把劍指offer的題目搞明白,其次再去刷LeetCode等習題,這樣對於面試突擊很是有用,由於面試官最常考的算法題都在這本書裏。算法

若是你發現看這本書很吃力,能夠先直接參考些網上的代碼,照着抄一遍,理解下算法題是應該解題,多抄幾道題目,你就對算法題的作法有感受了,這個高考作固定套路數學題是同樣的。編程

對於劍指offer題解這個系列,個人寫做思路是,對於看過文章的讀者,可以作到:後端

  • 迅速瞭解該題常看法答思路(奇技淫巧不包括在內,節省你們時間,實在有研究需求的人能夠查閱其它資料)
  • 思路儘可能貼近原書(例如書中提到的面試官常常會要求不改變原數組,或者有空間限制等,儘可能體如今代碼中,保證讀者能夠不漏掉書中細節)
  • 儘可能精簡話語,避免冗長解釋
  • 給出代碼可運行,註釋齊全,關注細節問題
  • 代碼可以經過牛客網在線編程《劍指offer》測試

《劍指offer題解》系列

你能夠經過如下幾種途徑查看個人《劍指offer題解》系列:數組

  • 關注個人公衆號:後端技術漫談,點擊公衆號導航欄:劍指offer題解
  • 劍指offer題解專欄(CSDN)
  • 各大博客平臺個人帳號(見本文最下方)

題目介紹

在一個二維數組中(每一個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。安全

解題思路

方法一

首先可以想到的確定是一行一行或者一列一列遍歷,判斷數組中是否含有該整數。該方法顯然是最笨拙的二維數組遍歷,面試官也不會滿意,時間複雜度是O(n^2)微信

代碼

Python

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)

代碼

Java

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;
    }
}

Python

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題解》系列

你能夠經過如下兩種途徑查看《劍指offer題解》系列:

  • 關注個人公衆號:後端技術漫談,點擊公衆號下方:劍指offer題解
  • 劍指offer題解專欄(CSDN導航頁)
  • 各平臺博客

關注我

我是一名後端開發工程師。

主要關注後端開發,數據安全,爬蟲,物聯網,邊緣計算等方向,歡迎交流。

各大平臺均可以找到我

  • 微信公衆號:後端技術漫談
  • Github:@qqxx6661
  • CSDN:@Rude3Knife
  • 知乎:@Zhendong
  • 簡書:@蠻三刀把刀
  • 掘金:@蠻三刀把刀
  • 頭條:@後端技術漫談

原創博客主要內容

  • Java知識點複習全手冊
  • Leetcode算法題解析
  • 劍指offer算法題解析
  • SpringBoot菜鳥入門實戰系列
  • SpringCloud菜鳥入門實戰系列
  • 爬蟲相關技術文章
  • 後端開發相關技術文章
  • 逸聞趣事/好書分享/我的興趣

我的公衆號:後端技術漫談

【劍指offer題解】二維數組中的查找
公衆號:後端技術漫談.jpg

若是文章對你有幫助,不妨收藏,投幣,轉發,在看起來~

相關文章
相關標籤/搜索