根據一棵樹的兩種遍歷構造二叉樹

題目

給定兩個整數數組?preorder?和?inorder?,其中?preorder?是二叉樹的先序遍歷,?inorder?是同一棵樹的中序遍歷,請構造二叉樹并返回其根節點。

示例 1:

輸入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
輸出: [3,9,20,null,null,15,7]

示例 2:

輸入: preorder = [-1], inorder = [-1]
輸出: [-1]

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder?和?inorder?均?無重復?元素
  • inorder?均出現在?preorder
  • preorder?保證?為二叉樹的前序遍歷序列
  • inorder?保證?為二叉樹的中序遍歷序列

前置知識:?

preorder?:前序遍歷(Preorder Traversal 亦稱先序遍歷)——訪問根結點--->根的左子樹--->根的右子樹。

inorder:中序遍歷(Inorder Traversal)——根的左子樹--->根節點--->根的右子樹

前序遍歷所得的第一個節點就是根節點,所以可以用來確定的是root根節點在中序遍歷的位置,

再根據中序遍歷,root根節點的左邊是這棵二叉樹的左樹,root根節點的右邊是這課二叉樹的右樹來構建這課二叉樹

以示例1為例談談對題目的理解

示例1輸入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

preorder = [??3,? 9,? 20,? 15,? 7? ]? ?3就為這棵二叉樹的root根節點

inorder = [? 9,??3,? 15,? 20,? 7? ]? 9為root的左樹,并且只有一個節點,所以9為root的左節點

15,20,7這三個節點為root的右樹,再根據中序遍歷根的左子樹--->根節點--->根的右子樹可得

root的右節點為20這個節點,20節點的左節點為15這個節點,右節點為7這個節點

畫圖演示上述文字說明


解題思路:

根據題目所給的前序遍歷的節點順序在中序遍歷中進行遞歸來構建二叉樹

1.根據前序遍歷找到中序遍歷根節點iRoot的位置,創建根節點,再確定iBegin,iEnd的位置,i++;

2.對iBegin和iEnd的位置進行判斷,當iBegin>iEnd時,返回null,遞歸開始回退;

2.在中序遍歷當中,根據iRoot ,iBegin,iEnd的位置,并進行左樹和右樹的構建;

對上述三步進行遞歸,遞歸完了之后,二叉樹構建完成,返回根節點root

注:對前序遍歷所得節點的利用才是本題代碼的靈魂所在

圖示:


解題代碼

class Solution {public int i = 0;public TreeNode buildTree(int[] preorder, int[] inorder) {return create_a_binary_tree(preorder, inorder, 0, inorder.length - 1);}public TreeNode create_a_binary_tree(int[] preorder, int[] inorder, int inBegin, int inEnd) {if (inBegin > inEnd) {return null;//給定的數組int[] preorder, int[] inorder,遍歷完了,沒有子樹了,該節點為空節點,返回null,遞歸開始回退}//先根據先序遍歷創建根節點TreeNode root = new TreeNode(preorder[i]);//找到當前根節點,在中序遍歷的位置int rootIndex = findIndex(inorder, inBegin, inEnd, preorder[i]);i++;//遞歸構建左樹root.left = create_a_binary_tree(preorder, inorder, inBegin, rootIndex - 1);//遞歸構建右樹root.right = create_a_binary_tree(preorder, inorder, rootIndex + 1, inEnd);//前序遍歷完成,返回根節點return root;}private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {for (int j = inBegin; j <= inEnd; j++) {if (inorder[j] == key) {return j;}}return -1;}
}

運行結果

題目鏈接

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/submissions/

舉一翻三,再來一道

根據一棵樹的中序遍歷與后序遍歷構造二叉樹

給定兩個整數數組?inorder?和?postorder?,其中?inorder?是二叉樹的中序歷,?postorder?是同一棵樹的后序遍歷,請你構造并返回這顆?二叉樹?。

示例 1:

輸入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
輸出:[3,9,20,null,null,15,7]

示例 2:

輸入:inorder = [-1], postorder = [-1]
輸出:[-1]

后序遍歷(Postorder Traversal)——根的左子樹--->根的右子樹--->根節點。
創建根節點后,先創建右數,再創建左樹

根據示例1進行講解,下圖是代碼遞歸過程

隨著代碼的遞歸,二叉樹隨之構建的過程?

?解題代碼

public class Solution {public int i = 0;public TreeNode buildTree(int[] inorder, int[] postorder) {i = postorder.length - 1;return create_a_binary_tree(postorder, inorder, 0, inorder.length - 1);}public TreeNode create_a_binary_tree(int[] postorder, int[] inorder, int inBegin, int inEnd) {if (inBegin > inEnd) {return null;//給定的數組int[] postorder, int[] inorder,遍歷完了,沒有子樹了,該節點為空節點,返回null,遞歸開始回退}//先根據先序遍歷創建根節點TreeNode root = new TreeNode(postorder[i]);//找到當前根節點,在中序遍歷的位置int rootIndex = findIndex(inorder, inBegin, inEnd, postorder[i]);i--;//遞歸先構建右樹root.right = create_a_binary_tree(postorder, inorder, rootIndex + 1, inEnd);//遞歸后構建左樹root.left = create_a_binary_tree(postorder, inorder, inBegin, rootIndex - 1);//前序遍歷完成,返回根節點return root;}private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {for (int j = inBegin; j <= inEnd; j++) {if (inorder[j] == key) {return j;}}return -1;}
}

運行結果

題目鏈接:

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/submissions/

完結撒花??ヽ(°▽°)ノ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39150.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39150.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39150.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity-Linux部署WebGL項目MIME類型添加

在以往的文章中有提到過使用IIS部署WebGL添加MIME類型使WebGL項目在瀏覽器中能夠正常加載&#xff0c;那么如果咱們做的是商業項目&#xff0c;往往是需要部署在學校或者云服務器上面的&#xff0c;大部分情況下如果項目有接口或者后臺管理系統&#xff0c;后臺基本都會使用Lin…

機器學習筆記:李宏毅ChatGPT Finetune VS Prompt

1 兩種大語言模型&#xff1a;GPT VS BERT 2 對于大語言模型的兩種不同期待 2.1 “專才” 2.1.1 成為專才的好處 Is ChatGPT A Good Translator? A Preliminary Study 2023 Arxiv 箭頭方向指的是從哪個方向往哪個方向翻譯 表格里面的數值越大表示翻譯的越好 可以發現專門做翻…

Ceph入門到精通-Linux下Ceph源碼編譯和GDB調試

Ceph版本&#xff1a;14.2.22 Linux版本&#xff1a;ubuntu-server 18.04 第一部分 下載Ceph源碼 1.1 配置Ceph源碼鏡像源 Ceph源碼是托管在Github上&#xff0c;由于某些原因&#xff0c;國內訪問Github網站很慢&#xff0c;所以需要從其他途徑加速獲取源碼。Github官方給出…

【ubuntu18.04】01-network-manager-all.yaml和interfaces和resolv.conf各有什么區別和聯系

文章目錄 01-network-manager-all.yaml、interfaces 和 resolv.conf 是與網絡配置相關的文件&#xff0c;它們在網絡設置中有著不同的作用和使用方式。 01-network-manager-all.yaml: 這是一個配置文件&#xff0c;通常在 Ubuntu 系統上使用 NetworkManager 進行網絡管理時使用…

ChatGPT?保密嗎?它有哪些潛在風險?如何規避?

自2022年11月公開發布以來&#xff0c;ChatGPT已成為許多企業和個人的必備工具&#xff0c;但隨著該技術越來越多地融入我們的日常生活&#xff0c;人們很自然地想知道&#xff1a;ChatGPT是否是保密的。 問&#xff1a;ChatGPT保密嗎&#xff1f; 答&#xff1a;否&#xff0…

C++11并發與多線程筆記(3)線程傳參詳解,detach()大坑,成員函數做線程函數

C11并發與多線程筆記&#xff08;3&#xff09;線程傳參詳解&#xff0c;detach 大坑&#xff0c;成員函數做線程函數 1、傳遞臨時對象作為線程參數1.1 要避免的陷阱11.2 要避免的陷阱21.3 總結 2、臨時對象作為線程參數2.1 線程id概念2.2 臨時對象構造時機抓捕 3、傳遞類對象…

VR時代真的到來了?

業界對蘋果的期待是&#xff0c;打造一臺真正顛覆性的&#xff0c;給頭顯設備奠定發展邏輯底座的產品&#xff0c;而實際上&#xff0c;蘋果只是發布了一臺更強大的頭顯。 大眾希望蘋果回答的問題是“我為什么需要一臺AR或者VR產品&#xff1f;”&#xff0c;但蘋果回答的是“…

從零開始學習 Java:簡單易懂的入門指南之MAth、System(十二)

常見API&#xff0c;MAth、System 1 Math類1.1 概述1.2 常見方法1.3 算法小題(質數)1.4 算法小題(自冪數) 2 System類2.1 概述2.2 常見方法 1 Math類 1.1 概述 tips&#xff1a;了解內容 查看API文檔&#xff0c;我們可以看到API文檔中關于Math類的定義如下&#xff1a; Math類…

每天一道leetcode:300. 最長遞增子序列(動態規劃中等)

今日份題目&#xff1a; 給你一個整數數組 nums &#xff0c;找到其中最長嚴格遞增子序列的長度。 子序列 是由數組派生而來的序列&#xff0c;刪除&#xff08;或不刪除&#xff09;數組中的元素而不改變其余元素的順序。例如&#xff0c;[3,6,2,7] 是數組 [0,3,1,6,2,2,7] …

【JavaEE進階】SpringBoot項目的創建

文章目錄 一. SpringBoot簡介1. 什么是SpringBoot?2. SpringBoot的優點 二. SpringBoot項目創建1. 使用IDEA創建2. 使用網頁創建SpringBoot項目 三. 運行SpringBoot項目 一. SpringBoot簡介 1. 什么是SpringBoot? Spring Boot 是一個用于快速構建基于 Spring 框架的應用程序…

Spring對象裝配

在spring中&#xff0c;Bean的執行流程為啟動spring容器&#xff0c;實例化bean&#xff0c;將bean注冊到spring容器中&#xff0c;將bean裝配到需要的類中。 既然我們需要將bea裝配到需要的類中&#xff0c;那么如何實現呢&#xff1f;這篇文章&#xff0c;將來闡述一下如何實…

SOFABoot——基本使用(筆記)

文章目錄 一、前言二、快速開始2.1 基本搭建2.2 測試是否成功2.3 其他部分日志測試異步啟動 三、SOFABoot的模塊化開發3.1 基于Spring上下文的隔離3.2 Root Application Context3.3 模塊并行化啟動3.4 JVM服務與RPC服務的發布與引用3.5 模塊配置Module-NameRequire-ModuleSprin…

wsl2安裝mysql環境

安裝完mysql后通過如下命令啟動mysql service mysql start 會顯示如下錯誤&#xff1a; mysql: unrecognized service 實際上上面顯示的錯誤是由于mysql沒有啟動成功造成的 我們要想辦法成功啟動mysql才可以 1.通過如下操作就可以跳過密碼直接進入mysql環境 2.如果想找到my…

微服務與Nacos概述-5

引入OpenFeign 添加依賴&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>com.alibaba.cloud</groupId>…

“記賬”很麻煩,看這場競賽中的隊伍與合合信息是如何解決問題的

在我們日常生活中或多或少都會有記賬的情況&#xff0c;以此來對自己的收支和消費習慣進行分析&#xff0c;來幫助自己減少不必要的開支&#xff0c;優化財務決策、合理分配資金&#xff0c;減少財務壓力和不必要的浪費。 但記賬這個動作本身就是一件比較麻煩的。雖然現階段有…

數據結構入門 — 時間復雜度、空間復雜度

前言 數據結構_空間復雜度_時間復雜度講解_常見復雜度對比 本文介紹數據結構中的時間復雜度和空間復雜度 ***文章末尾&#xff0c;博主進行了概要總結&#xff0c;可以直接看總結部分*** 博主博客鏈接&#xff1a;https://blog.csdn.net/m0_74014525 點點關注&#xff0c;后期…

哈夫曼樹(赫夫曼樹、最優樹)詳解

目錄 哈夫曼樹&#xff08;赫夫曼樹、最優樹&#xff09;詳解 哈夫曼樹相關的幾個名詞 什么是哈夫曼樹 構建哈夫曼樹的過程 哈弗曼樹中結點結構 構建哈弗曼樹的算法實現 哈夫曼樹&#xff08;赫夫曼樹、最優樹&#xff09;詳解 哈夫曼樹相關的幾個名詞 路徑&#xff1a;…

2023牛客暑期多校訓練營8(A/H/I/J)

目錄 A.Alive Fossils H.Insert 1, Insert 2, Insert 3, ... I.Make It Square J.Permutation and Primes A.Alive Fossils 思路&#xff1a;一開始題意看半天沒看懂&#xff0c;后面發現只需要輸出t組輸入中&#xff0c;都出現過的字符串即可。 代碼&#xff1a; void s…

實驗三 圖像分割與描述

一、實驗目的&#xff1a; &#xff08;1&#xff09;進一步掌握圖像處理工具Matlab&#xff0c;熟悉基于Matlab的圖像處理函數。 &#xff08;2&#xff09;掌握圖像分割方法&#xff0c;熟悉常用圖像描述方法。 二、實驗原理 1.膚色檢測 膚色是人類皮膚重要特征之一&#xff…

7.原 型

7.1原型 【例如】 另外- this指向&#xff1a; 構造函數和原型對象中的this都指向實例化的對象 7.2 constructor屬性 每個原型對象里面都有個constructor屬性( constructor構造函數) 作用&#xff1a;該屬性指向該原型對象的構造函數 使用場景: 如果有多個對象的方法&#…