前端程式員學好演算法系列(七)二叉樹和遞歸

来源:https://www.cnblogs.com/kbnet/archive/2020/07/27/13387144.html
-Advertisement-
Play Games

144. 二叉樹的前序遍歷給定一個二叉樹,返回它的 前序 遍歷。 示例: 輸入: [1,null,2,3] 1 \ 2 / 3 輸出: [1,2,3] 有兩種通用的遍歷樹的策略: 深度優先搜索(DFS) 在這個策略中,我們採用深度作為優先順序,以便從跟開始一直到達某個確定的葉子,然後再返回根到達另一個 ...


144. 二叉樹的前序遍歷
給定一個二叉樹,返回它的 前序 遍歷。

示例:

輸入: [1,null,2,3] 
1
\
2
/
3

輸出: [1,2,3]

有兩種通用的遍歷樹的策略:

深度優先搜索(DFS)

在這個策略中,我們採用深度作為優先順序,以便從跟開始一直到達某個確定的葉子,然後再返回根到達另一個分支。

深度優先搜索策略又可以根據根節點、左孩子和右孩子的相對順序被細分為前序遍歷,中序遍歷和後序遍歷。

寬度優先搜索(BFS)

我們按照高度順序一層一層的訪問整棵樹,高層次的節點將會比低層次的節點先被訪問到。

下圖中的頂點按照訪問的順序編號,按照 1-2-3-4-5 的順序來比較不同的策略。

 

解題:
1. 前序遍歷口訣,遞歸終止條件 if(root==null) return
2. 前序遍歷先列印root的值,遞歸遍歷root的左子樹, 遞歸調用root的又子樹

3. 中序遍歷 先遞歸遍歷root的左子樹,列印root的值, 遞歸調用root的又子樹

4. 後序遍歷 先遞歸遍歷root的左子樹, 在遞歸調用root的又子樹, 列印root的值

5.前中後序遍歷的不同之處在於列印root.val的時機,掌握一種,其他也很好掌握

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
     let res = []
     function pre(root){
         if(root==null){
             return
         }
         res.push(root.val)
         if(root.left){
              pre(root.left)
         }
         if(root.right){
              pre(root.right)
         }
     }
     pre(root)
     return res
};

104. 二叉樹的最大深度
給定一個二叉樹,找出其最大深度。

二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。

說明: 葉子節點是指沒有子節點的節點。

示例:

給定二叉樹 [3,9,20,null,null,15,7],

3
/ \
9 20
/ \
15 7
返回它的最大深度 3

解題:

我們知道,二叉樹每個節點的深度與它左右子樹的深度有關,且等於其左右子樹最大深度值加上 1 。即:maxDepth(root) = max(maxDepth(root.left),maxDepth(root.right)) + 1

以 [3,4,20,null,null,15,7] 為例:

<1>我們要對根節點的最大深度求解,就要對其左右子樹的深度進行求解

<2>我們看出。以4為根節點的子樹沒有左右節點,其深度為 1 。而以 20 為根節點的子樹的深度,同樣取決於它的左右子樹深度。



<3>對於15和7的子樹,我們可以看出其深度為 2

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    if(root==null){
        return 0
    }
    return Math.max(maxDepth(root.left),maxDepth(root.right))+1
};

226. 翻轉二叉樹
翻轉一棵二叉樹。

示例:

輸入:

4
/ \
2 7
/ \ / \
1 3 6 9
輸出:

4
/ \
7 2
/ \ / \
9 6 3 1

解題:

1.js交換兩個值A,B的重要事項 先緩存A  let tmp = A  ; 把A賦值B A = B; 把B賦值為緩存的tmp

2.我們這裡也一樣 遞歸終止條件 if(!root) return null

3.root存在時交換左右節點,在遞歸調用

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
    if(!root) return null
    if(root) {
        var left = root.left
        root.left = root.right
        root.right = left
    }
    invertTree(root.left)
    invertTree(root.right)
    return root
};

112. 路徑總和
給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。

說明: 葉子節點是指沒有子節點的節點。

示例: 

給定如下二叉樹,以及目標和 sum = 225
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1

返回 true, 因為存在目標和為 22 的根節點到葉子節點的路徑 5->4->11->2。

解題:

1.求解從 root 到葉子節點是否存在路徑和為 sum 的路徑 hasPathSum(root, sum),可以轉換成求解從 root.left 或者 root.right 到葉子節點是否存在路徑和為 sum - root.val 的路徑,即 hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val) 。

2.本題要求必須有葉子節點所有 當root只有一個元素且root.val ==sum時不是一個正確的解。
3.我們用 root.left==null && root.right==null 時判斷最正確的解。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} sum
 * @return {boolean}
 */
var hasPathSum = function(root, sum) {
      if(root==null){
          return false
      }
      if(root.left==null && root.right==null){
          return sum == root.val
      }
      if(hasPathSum(root.left,sum-Number(root.val))){
          return true
      }
      if(hasPathSum(root.right,sum-Number(root.val))){
          return true
      }
      return false
};

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HTML元素指的是從開始標簽( start tag)到結束標簽( end tag)的所有代碼 開始標簽元素內容結束標簽 <p> this is a paragraph </p> <a href="default.htm"> this is a link </a> <br/> 註釋:開始標簽被稱為開放 ...
  • 60個\參考網址https://www.w3school.com.cn/tags/index.asp 標簽描述 <!--...--> 定義註釋。 <!DOCTYPE> 定義文檔類型。 <a> 定義錨。 <abbr> 定義縮寫。 <acronym> 定義只取首字母的縮寫。 <address> 定義文檔 ...
  • HTML:超文本標記語言,是使用標記標簽來描述網頁的一種語言,也是一種規範,一種標準,它通過標記符號來標記要顯示的網頁中的各個部分; css層疊樣式表是一種用來表現HTML(標準通用標記語言的一個應用)或XML(標準通用標記語言的一個子集)等文件樣式的的電腦語言。css不僅可以靜態地修飾網頁,還可 ...
  • HTML基本結構 document是指整個文件,它下麵就是咱們的html 超文本標記語言的結構包括"頭"(head)和主體(body) 其中"頭"部提供關於網頁的信息,"主體"部分提供網頁的具體內容 #HTML基本結構-文檔聲明 為了說明文檔使用的超文本標記原因標準,所有的超文本標記語言文檔應該以“ ...
  • 一夜無眠,學習不是為了別人,自己執行力好差,對自己過高期望,以為任務目標Soeasy,結果徘徊了幾個月,還是在原地踏步,怎麼講了?學習還是要腳踏實地,專註,不要為自己找藉口!畢竟虛長幾歲,曾經的年少輕狂高傲、曲動琴聲美妙一不復返!如今的自己在為曾經的不學習,努力向著生活買單!希望下麵可以越來越好! ...
  • 回溯演算法主要應用於樹形問題,我們先從一個簡單的演算法入手 17. 電話號碼的字母組合給定一個僅包含數字 2-9 的字元串,返回所有它能表示的字母組合。 給出數字到字母的映射如下(與電話按鍵相同)。註意 1 不對應任何字母。 示例: 輸入:"23" 輸出:["ad", "ae", "af", "bd", ...
  • 一、文檔載入模式 1.事件 三要素:事件源(觸發時間的元素);事件名稱(click點擊事件);事件處理程式(事件出發後要執行的代碼函數形式) 存在問題:瀏覽器載入一個頁面的時候,是按照自上而下的順序載入的,若將script標簽寫到head內部,在代碼執行時候,頁面還沒有載入,頁面中的DOM對象也沒有 ...
  • 作者:吉玉 智能化測試 在互動中經常需要維護大量的狀態,對這些狀態進行測試驗證成本較高,尤其是當有功能變動需要回歸測試的時候。為了降低開發測試的成本,在這方面使用強化學習模擬用戶行為,在兩個方面提效: mock介面:將學習過程中的狀態作為服務介面的測試數據; 回歸測試:根據mock介面數據回溯到特定 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...