別再翻了,面試二叉樹看這 11 個就夠了~

寫在前邊

數據結構與算法:javascript

不知道你有沒有這種困惑,雖然刷了不少算法題,當我去面試的時候,面試官讓你手寫一個算法,可能你對此算法很熟悉,知道實現思路,可是老是不知道該在什麼地方寫,並且不少邊界條件想不全面,一緊張,代碼寫的亂七八糟。若是遇到沒有作過的算法題,思路也不知道從何尋找。面試吃了虧以後,我就慢慢的作出總結,開始分類的把數據結構全部的題型和解題思路每週刷題作出的系統性總結寫在了 Github。歡迎關注和 star: 「數據結構與算法倉庫前端

PS:若是你剛剛在學習數據結構和算法,請務必把最簡單的題弄懂,全部的入門的數據結構與算法從簡單到複雜進行了全面的梳理。 「初學者必會的 30 道數據結構與算法java

若是你對數據結構和算法有了必定的瞭解和認識,上邊的入門算法題已經能夠輕鬆實現,那麼能夠嘗試着解決 LeetCode 上總結的 30 道題,我把解題思路、測試用例、代碼實現作了詳細的整理,建議先本身嘗試的解決哦,收藏 + 關注,歡迎 Star。「必會的 30 道 LeetCode 經典算法題git

網絡協議原理:github

除了算法以外,面試最注重的就是網絡原理,由於我自己上的學校很爛,課上只是講點皮毛,當時也沒重視這一塊,因此在大三面試的時候吃了大虧,而後開始重視了起來,這部分雖然理論上偏多,可是從最基礎的開始學習須要有個引導,上來就是 TCP 和 HTTP,想必學起來很吃力吧。而後我嘗試着去根源上學習網絡原理,爲何會有這些,因此邊學習,邊整理成了文章分享給學習網絡原理這一塊的內容,每週 Github 都會更新~ 「猛戳這裏查看倉庫面試


--- 一下是正文 ----算法

《劍指 offer》是準備數據結構與算法面試的一本好書,裏邊不少面試手寫算法不少的注意的問題,可是基本都是用 C++ 實現的,書中每章節的分類都是按照性能和消耗以及手寫代碼的注意的幾大點進行了分類,針對每一個不一樣的點,進行數據結構與算法的混合實現。編程

二遍刷題,發現了還能夠根據自身狀況進行整理和分類。所有代碼是用 JS 書寫,都通過 Leetcode 標準測試(小部分Leetcode 沒有的題目),對全部的算法題的特色進行總結分類,手寫算法中,如何考慮到所有的邊界條件;若是快速多種思路解決,如何將思路快速的轉化爲代碼,這是這一篇重點分享的地方。數組

二叉樹題目共有 11 題,我把這 11 題書中對實現方法和思路有詳細的講解,可是對於我的來講,之後遇到陌生的二叉樹的題目怎麼進行解決,經過對 11 個題的分析、整理,得出如下幾個步驟,首先先來看這 11 個二叉樹經典算法題。網絡

PS:若是你已經作過這幾道題,並且可以順利的手寫出來,不妨滑到最底部,但願最後的二叉樹思路、測試用例以及代碼編寫的總結對你在面試中有所幫助(這篇文章精華所在)。


11 道精華二叉樹面試題

1.1 面試題7:重建二叉樹

已知前序遍歷爲{1,2,4,7,3,5,6,8},中序遍歷爲{4,7,2,1,5,3,8,6},它的二叉樹是怎麼樣的?

一、思路

根據前、中序遍歷的特色,(根左右、左根右),先根據前序遍歷肯定根節點,而後在中序遍歷知道該根節點的左右樹的數量,反推出前序遍歷中左子樹的結點有哪些。根據該思路進行遞歸便可完成二叉樹的重建。

二、 測試用例

  • 徹底二叉樹、非徹底二叉樹 —— 普通測試。
  • 只有左子節點二叉樹,只有右子節點、只有一個結點的二叉樹 —— 特殊二叉樹測試。
  • 空樹、前序和中序不匹配 —— 輸入測試。

三、代碼實現

1 // 定義結點
 2 // class TreeNode{
 3 // constructor(data){
 4 // this.data = data;
 5 // this.left = null;
 6 // this.right = null;
 7 // } 
 8 // }
 9
10 // 參數:前序遍歷數組 ~ 中序遍歷數組
11 const reConstructBinaryTree = (pre, vin)=>{
12    // 判斷前序數組和中序數組是否爲空
13    if(!pre || pre.length === 0 || !vin || vin.length === 0){
14        return;
15    }
16    // 新建二叉樹的根節點
17    var treeNode = {
18        val: pre[0]
19    }
20    // 查找中序遍歷中的根節點
21    for(var i = 0; i < pre.length; i++) {
22        if (vin[i] === pre[0]) {
23            // 將左子樹的前中序遍歷分割開
24            treeNode.left = reConstructBinaryTree(pre.slice(1, i+1), vin.slice(0, i));
25            // 將右子樹的前中序遍歷分割開
26            treeNode.right = reConstructBinaryTree(pre.slice(i+1),vin.slice(i+1));
27        }
28    }
29    // 返回該根節點
30    return treeNode;
31 }
32
33 let pre = [1,2,4,7,3,5,6,8]; // 前序遍歷
34 let vin = [4,7,2,1,5,3,8,6]; // 中序遍歷 
35 console.log(reConstructBinaryTree(pre,vin));
複製代碼

1.2 二叉樹的下一節點

給定一個二叉樹的節點,如何找出中序遍歷的下一節點。有兩個指向左右子樹的指針,還有一個指向父節點的指針。

面試題8:[題目解析]


1.3 樹的子結構

輸入兩棵二叉樹 A 和 B,判斷 B 是否是 A 的子結構。

面試題26:[題目解析]


1.4 二叉樹的鏡像

請完成一個函數,若是一個二叉樹,該函數輸出它的鏡像。

面試題27:[題目解析]


1.5 對稱二叉樹

請實現一個函數,用來判斷一棵二叉樹是否是對稱的。若是一棵二叉樹和它的鏡像同樣,那麼它是對稱的。

面試題28:[題目解析]


1.6 從上到下打印二叉樹

從上到下打印出二叉樹的每一個節點,同一層的節點按照從左到右的順序打印。(按層遍歷二叉樹)

面試題32:[題目解析]


1.7 二叉樹的後序遍歷序列

輸入一個整數數組,判斷該數組是否是某二叉搜索樹的後續遍歷。若是是返回 true,若是不是返回 false。假設輸入的任意兩個數字互不相同。

面試題33:[題目解析]


1.8 二叉樹和爲某一值路徑

輸入一棵二叉樹和一個整數,打印出二叉樹中節點值的和爲輸出整數的全部路徑。從樹的根節點開始往下一直到葉子節點所通過的節點造成一條路徑。

面試34:[題目解析]


1.9 序列化二叉樹

請實現兩個函數,分別用來序列化二叉樹和反序列化二叉樹。

面試題37:[題目解析]


1.10 二叉樹的第 K 大節點

給定一棵二叉搜索樹,請找出其中的第 K 大節點。

面試題54:[題目解析]


1.11 二叉樹的深度

輸入一棵二叉樹的根節點,求該樹的深度。從根節點到葉子節點依次通過的節點(包含根、葉子節點)造成樹的一條路徑,最長路徑的長度樹的深度。

面試題55:[題目解析]


總結概括

經過《劍指 offer》以上十一個題,不是作過以後就記住了這麼簡單,而是經過以上二叉樹題型的總結概括,能不能觸類旁通,總結出二叉樹面試題的解題思路,之後遇到二叉樹相面試題能不能經過上邊總結出來的步驟進行思考獨立解決,這是這篇文章的重點。下面就分別經過解題思路、測試用例以及編寫代碼進行深刻總結。

1、解題思路總結

一、根據樹前(根左右)、中(左根右)、後(左右根)序遍歷的規律來解決問題。

經過二叉樹的遍從來找到規律,從而找到解題思路。

  • 重建二叉樹

    根據前、中序遍歷,找到二叉樹的根節點和左右子樹的規律,而後遞歸構建二叉樹。

  • 二叉樹的下一節點

    根據中序遍歷,找出包含任何節點的一下節點的全部可能狀況,而後根據狀況分別進行判斷。

  • 二叉樹的後續遍歷序列

    經過中序遍歷找到打印二叉樹結點的規律,能夠判斷此後續遍歷是否爲二叉樹。

  • 二叉樹和爲某一值的路徑

    選擇二叉樹的遍歷,對每一個節點進行存儲判斷,而後根據二叉樹葉子節點的特色,進行對問題的解決。

  • 二叉樹的第 K 大結點

    中序遍歷的結果是從小到大,而後倒數找到第 K 大數據。

  • 序列化二叉樹

    遍歷二叉樹,遇到 null 轉化爲特殊符號。


二、根據樹的結構尋找規律來解決問題

經過二叉樹的特色:左子節點小於父節點、右子節點大於父節點、樹的節點能夠進行遞歸等,以上特色又是更好的幫咱們解決思路。

  • 樹的子結構

    根據子結構和主體樹的特色,對其樹的結構進行分析,能夠找到解題的思路。

  • 鏡像二叉樹

    觀察鏡像二叉樹的左右子節點交換特色,能夠找到解題思路。

  • 對稱二叉樹

    觀察對稱二叉樹有什麼特色,在結構上和遍歷上尋找特色和規律,能夠找到解題思路。

  • 按層遍歷二叉樹

    根據二叉樹每層節點的結構關係(父子關係),能夠進行每層遍歷,經過上層找到下層的遍歷結點。

  • 反序列化二叉樹

    根據遍歷的規律和二叉樹的規律,將遍歷結果生成一棵二叉樹。


2、測試用例

經過以上題目中,我將測試用例分爲三大種,測試代碼的時候,在這三大種進行想就能夠了。

  • 普通測試
  • 特殊測試
  • 輸入測試

一、普通測試

普通測試從兩個方面去想,第一個方面就是問題的自己,好比對稱二叉樹的判斷,普通測試就是分別輸入一個對稱二叉樹和非對稱二叉樹進行測試。第二個方面就是問題自己沒有什麼能夠找到的測試,好比按層遍歷二叉樹,它的普通測試就是分別輸入徹底二叉樹(普通二叉樹也能夠),非徹底二叉樹進行測試。


二、特殊測試

特殊測試強調的是樹的特殊性,特殊的二叉樹就那麼幾個,好比:只有左子節點的二叉樹、只有右子節點的二叉樹、只有一個節點的二叉樹、沒有結點的二叉樹。


三、輸入測試

輸入測試,顧名思義,要對用戶輸入的參數進行判斷,好比,你輸入一棵樹,要判斷是否爲空。再好比,求最大 K 結點,對 K 的取值範圍進行判斷。


3、代碼編寫

將二叉樹的解題思路轉化爲代碼除了熟練最基本的二叉樹的增、刪、改、查以外,最重要的就是二叉樹的遞歸,由於二叉樹的結構決定了用遞歸解決二叉樹問題更加簡便。可是遞歸的書寫並不只簡單,由於它有遞和歸的過程,大腦並不能更好的去處理這些,能夠去看以前總結遞歸的文章《數據結構與算法之遞歸系列》。

書寫二叉樹遞歸問題有一點特別重要,不要嘗試的去想那個遞歸的過程,而是先去尋找到遞歸的終止條件,而後對每次遞歸的結果進行判斷,而後讓他遞歸去吧,再次強調千萬別去思考過程。

後記

刷了一遍劍指 offer 沒有領略到這些題的精華所在,而後開始刷第二遍、第三遍、第四遍... 逐漸的對同一類型的題作出總結,第一週完成了全部二叉樹面試題的總結,下一週會選擇下一類型面試題進行攻克,打算用兩個月的時間,將劍指 offer 全部的面試題型進行體系化的總結、概括,邊學習、邊分享。「猛戳劍指 offer 倉庫,和我一塊兒打卡


❤️ 不要忘記留下你學習的腳印 [點贊 + 收藏 + 評論]

一切看文章不點贊都是「耍流氓」,嘿嘿ヾ(◍°∇°◍)ノ゙!開個玩笑,動一動你的小手,點贊就完事了,你每一個人出一份力量(點贊 + 評論)就會讓更多的學習者加入進來!很是感謝! ̄ω ̄=


做者Info:

做者:小鹿

原創公衆號:小鹿動畫學編程 簡介:和小鹿同窗一塊兒用動畫的方式從零基礎學編程,將 Web前端領域、數據結構與算法、網絡原理等通俗易懂的呈獻給小夥伴。 轉載說明:轉載請說明出處[juejin.im/post/5d7596…],謝謝合做!

相關文章
相關標籤/搜索