Java LeetCode篇-深入了解二叉樹的經典解法(多種方式實現:構造二叉樹)

🔥博客主頁:?【小扳_-CSDN博客】
?感謝大家點贊👍收藏?評論?
???

文章目錄

????????1.0 從前序與中序遍歷序列來構造二叉樹

? ? ? ? 1.1 實現從前序與中序遍歷序列來構造二叉樹思路? ?

? ? ? ? 1.2 代碼實現從前序與中序遍歷序列來構造二叉樹

? ? ? ? 2.0 從中序與后序遍歷序列構造二叉樹

? ? ? ? 2.1 實現從中序與后序遍歷序列后遭二叉樹思路

? ? ? ? 2.2 代碼實現從中序與后序遍歷序列來構造二叉樹

? ? ? ? 3.0 根據后綴表達式創建二叉樹

? ? ? ? 3.1 實現后綴表達式創建二叉樹思路

? ? ? ? 3.2 代碼實現后綴表達式創建二叉樹

? ? ? ? ?4.0 相同的樹

? ? ? ? 4.1 實現判斷兩顆樹是否相同思路

? ? ? ? 4.2 代碼實現相同樹

? ? ? ? ?5.0 另一顆樹的子樹

????????5.1 實現判斷是否為另一顆樹的子樹

????????5.2 代碼實現判斷是否為另一顆樹的子樹


????????1.0 從前序與中序遍歷序列來構造二叉樹

題目:

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

示例 1:

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

OJ鏈接:

105.?從前序與中序遍歷序列構造二叉樹

? ? ? ? 1.1 實現從前序與中序遍歷序列來構造二叉樹思路? ?

????????具體思路為:前序遍歷的流程先是訪問根節點,到左子樹,再到右子樹的順序;中序遍歷的流程先是左子樹,到訪問根節點,再到右子樹。因此,在前序的序列中的第一個元素就是該樹的根節點的值,然后再通過中序的序列中遍歷找根節點。接著就可以將其中序的序列進行拆分,在中序序列中根節點的值的左邊部分的序列為左子樹,在中序序列中根節點的值的右邊部分序列為右子樹。又接著將前序序列進行拆分,從索引為 1 開始,長度為:與中序序列中左子樹的序列數量是一致的,將這一部分稱為左子樹;從索引 (1+長度)開始到該序列的結束,將這一部分稱為右子樹。接下來就是子問題了,通過遞歸,找到當前節點的左右子樹。

? ? ? ?具體例子:前序序列 pre = {3,9,20,15,7},中序序列 in = {9,3,15,20,7} 。先找到該樹的節點值 int rootValue = pre[0], TreeNode root = new TreeNode(rootValue),創建該樹的根節點。接著對中序序列遍歷來找到根節點的值,i == 1 ,在中序序列中找左右子樹:在索引在該區間 [0,1)是節點的左子樹,而在索引為?[2,5)區間是節點的右子樹。在前序序列中找左右子樹:在索引為 [1,2)是該節點的左子樹,而在索引為 [2,5)區間是節點的右子樹。

? ? ? ? 子問題:那么現在得到了左子樹的前序序列 pre = { 9 } ,左子樹的中序序列 in = { 9 },接下來的流程跟以上的流程是一樣的,先找到該子樹的根節點值 9 ,然后創建一個值為 9 的根節點。接著,遍歷中序序列來找到根節點的值,該根節點的左部分就是左子樹,該節點的右部分就是右子樹。那么這里的左右子樹都為空,因此節點為 9 的根節點沒有左右子樹了。

? ? ? ? 往上回溯:來到根節點值為 3 的節點。現在得到了右子樹的前序序列 pre = {20,15,7} ,右子樹的中序序列 in = {15,20,7} ,接下來的過程是一摸一樣的,先找到該子樹的根節點值為 20 ,創建值為 20 的根節點。然后在中序序列中進行遍歷找到根節點的左右子樹 :左子樹序列為 {15},右子樹序列為 {7},接著在前序序列中找左右子樹:左子樹序列為 {15},右子樹序列為 {7} 。又得到了左右前中序列,按同樣的道理繼續下去即可,通過上面的結論,當左子樹前序 {15} 與左子樹中序 {15} 一樣時,那么在當前的節點值為 15 的根節點沒有左右子樹了。同理,當右子樹前序 {7} 與右子樹中序 {7} 一樣時,那么在當前的節點值為 7 的根節點沒有左右子樹了。

? ? ? ? 最后回溯,根節點值為 20 的左子樹的根節點為 15,右子樹的根節點為 7 ,鏈接起來,一直回溯到結束返回的最后的節點就是該樹的根節點(值為 1 的根節點)。

? ? ? ? 需要注意的是:注意左閉右開。因為是同一顆樹,在前序中的左右子樹的長度跟中序中的左右子樹的長度是一樣的。

? ? ? ? 1.2 代碼實現從前序與中序遍歷序列來構造二叉樹

    //根據前序與中序來構造二叉樹public TreeNode prevAndInOrderConstructTree(int[] prevOrder, int[] inOrder) {if (prevOrder.length == 0) {return null;}int rootValue = prevOrder[0];TreeNode root = new TreeNode(rootValue);for (int i = 0; i < inOrder.length; i++) {if (inOrder[i] == rootValue) {int[] inLeft = Arrays.copyOfRange(inOrder,0,i);int[] inRight = Arrays.copyOfRange(inOrder,i+1,inOrder.length);int[] prevLeft = Arrays.copyOfRange(prevOrder,1,i + 1);int[] prevRight = Arrays.copyOfRange(prevOrder,i+1,inOrder.length);root.left = prevAndInOrderConstructTree(prevLeft,inLeft);root.right = prevAndInOrderConstructTree(prevRight,inRight);}}return root;}

? ? ? ? 只要某一個序列無論是前序或者是中序序列的長度為 0 ,都代表創建二叉樹過程結束了。

? ? ? ? 2.0 從中序與后序遍歷序列構造二叉樹

題目:

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

示例 1:

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

OJ鏈接:

106.?從中序與后序遍歷序列構造二叉樹

? ? ? ? 2.1 實現從中序與后序遍歷序列后遭二叉樹思路

? ? ? ? 具體思路為:中序的序列先訪問左子樹,再訪問根節點,最后到右子樹。后序的序列先訪問左子樹,再訪問右子樹,最后才到根節點。因此,可以從后序序列中的最后一個元素得到根節點的值,然后利用該值來創建根節點。接著,在中序序列中遍歷查找根節點的值,在中序序列中根節點值左邊的序列為左子樹序列,在中序序列中根節點的右邊為右子樹的序列。再接著再后序中獲取左子樹的序列:從索引為 0 開始長度是中序序列得到的左子樹的長度;從后序序列中獲取右子樹序列:除了左子樹的序列和根節點值元素,其余就是右子樹的序列了。接下來就是子問題了,遞歸下去,返回當前的根節點。

? ? ? ? 具體例子:中序序列 in = {9,3,15,20,7},后序序列 post = {9,15,7,20,3},通過后序得到該樹的根節點的值 3,由這個值來創建值為 3 的根節點。接著通過遍歷中序序列,找到值為 3 來定位左右子樹,左子樹的序列為:{9} ,右子樹的序列為:{15,20,7} 。再從中序序列中定位左右子樹,左子樹為:{9},右子樹為:{15,7,20} 。現在得到了左右中后序列,中序左子樹:{9} ,后序左子樹:{9},通過后序得到根節點,再從中序定位該子樹的根節點,這里根節點值為 9 的根節點的左右子樹均為 null 。接著回溯,返回的該子樹的根節點。

? ? ? ? 再到右子樹中序 {15,20,7} ,右子樹后序 {15,7,20},通過后序序列的最后一個值來創建該子樹的根節點,在中序中遍歷找到該根節點的值,定位該節點的左右子樹。中序的左子樹序列 {15},右子樹序列 {7};后序的左子樹序列 {15},后序的右子樹序列 {7} 。

? ? ? ? 再接著遞歸,得到左子樹中序 {15} ,左子樹后序 {15}。通過后序的最后一個元素就是根節點的值來創建該子樹的根節點,然后在中序中定位該根節點的左右子樹,這里的左右子樹都為 null ,返回根節點即可。得到右子樹中序 {7},右子樹后序 {7},通過后序的最后一個元素為根節點的值來創建該子樹的根節點,然后在中序中定位該根節點的左右子樹,恰好,這里的左右子樹都為 null ,返回根節點即可。

? ? ? ? 最后回溯過程,根節點值為 1 的節點的左子樹的根節點為 9 的節點,右子樹的根節點為 20 的節點。

? ? ? ? 2.2 代碼實現從中序與后序遍歷序列來構造二叉樹

    //根據中序與后序來構造二叉樹public TreeNode inAndPostConstructTree(int[] inOrder, int[] postOrder) {if (inOrder.length == 0) {return null;}int rootValue = postOrder[postOrder.length-1];TreeNode root = new TreeNode(rootValue);for (int j = 0; j < inOrder.length; j++) {if (rootValue == inOrder[j]) {int[] inLeft = Arrays.copyOfRange(inOrder,0,j);int[] inRight = Arrays.copyOfRange(inOrder,j+1,inOrder.length);int[] postLeft = Arrays.copyOfRange(postOrder,0,j);int[] postRight = Arrays.copyOfRange(postOrder,j,postOrder.length-1);root.left = inAndPostConstructTree(inLeft,postLeft);root.right = inAndPostConstructTree(inRight,postRight);}}return root;}

? ? ? ? 需要注意的定位左右子樹的序列長度,中序與后序的左右子樹都是一一對應的。也因此,當無論任意一個序列結束,都代表著構造二叉樹過程結束。

? ? ? ? 3.0 根據后綴表達式創建二叉樹

????????后綴表達式也叫逆波蘭表達式,是一種不需要括號的表達式表示方法。在后綴表達式中,運算符總是在操作數的后面,因此可以通過從左到右掃描表達式來創建二叉樹。

? ? ? ? 3.1 實現后綴表達式創建二叉樹思路

? ? ? ? 具體思路為:若遇到數字將其壓入棧中;若遇到操作符時,將棧中的右左元素彈出棧,操作符節點進行鏈接彈出來的左右子樹,需要注意的是,第一個彈出來的是右操作數,第二個才是左操作數。鏈接完之后,將其壓入棧中即可。循環結束條件為:將后綴表達式遍歷完就結束。最后返回棧中的棧頂元素,就是該樹的根節點。

? ? ? ? 3.2 代碼實現后綴表達式創建二叉樹

    //根據后綴表達式創建二叉樹public TreeNode suffixCreateTree(String[] s) {LinkedList<TreeNode> stack = new LinkedList<>();for (int i = 0; i < s.length; i++) {String ch = s[i];switch (ch) {case "+","-","*","/" -> {TreeNode right = stack.pop();TreeNode left = stack.pop();TreeNode t = new TreeNode(ch);t.right = right;t.left = left;stack.push(t);}default -> {stack.push(new TreeNode(ch));}}}return stack.peek();}

? ? ? ? ?4.0 相同的樹

題目:

????????給你兩棵二叉樹的根節點?p?和?q?,編寫一個函數來檢驗這兩棵樹是否相同。

如果兩個樹在結構上相同,并且節點具有相同的值,則認為它們是相同的。

示例 1:

輸入:p = [1,2,3], q = [1,2,3]
輸出:true

OJ鏈接:

100.?相同的樹

? ? ? ? 4.1 實現判斷兩顆樹是否相同思路

? ? ? ? 具體思路為:使用遞歸實現,第一種情況:若一個子樹為 null ,另一個子樹不為 null ,返回 false ;第二種情況:若兩個子樹都為 null ,則返回 true 。第三種情況:若兩個子樹的根節點的值不相同時,返回 false 。子過程,判斷完左子樹,還需判斷右子樹。

? ? ? ? 4.2 代碼實現相同樹

class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if( p != null && q == null || p ==null && q != null) {return false;}if(p == null && q == null ){return true;}if(p.val != q.val) {return false;}return isSameTree(p.left, q.left) && isSameTree(p.right,q.right);}
}

? ? ? ? 5.0 另一顆樹的子樹

題目:

????????給你兩棵二叉樹?root?和?subRoot?。檢驗?root?中是否包含和?subRoot?具有相同結構和節點值的子樹。如果存在,返回?true?;否則,返回?false?。

二叉樹?tree?的一棵子樹包括?tree?的某個節點和這個節點的所有后代節點。tree?也可以看做它自身的一棵子樹。

示例 1:

輸入:root = [3,4,5,1,2], subRoot = [4,1,2]
輸出:true

OJ鏈接:

572.?另一棵樹的子樹

? ? ? ? ?5.1 實現判斷是否為另一顆樹的子樹

? ? ? ? 具體思路為:最根本的問題就是判斷是否為相同的樹,判斷該樹的子樹與另一顆子樹是否相同,不斷遞歸下去,只要相同就返回 true 。直到最后遞歸結束都沒有匹配,則返回 false 。

? ? ? ? 5.2 代碼實現判斷是否為另一顆樹的子樹

class Solution {public boolean isSubtree(TreeNode root, TreeNode subRoot) {if(root == null) {return false;}if(isSameTree(root,subRoot)) {return true;}if(isSubtree(root.left,subRoot)) {return true;}if(isSubtree(root.right,subRoot)) {return true;}return false;}public boolean isSameTree(TreeNode p, TreeNode q) {if( p != null && q == null || p ==null && q != null) {return false;}if(p == null && q == null ){return true;}if(p.val != q.val) {return false;}return isSameTree(p.left, q.left) && isSameTree(p.right,q.right);}
}

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

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

相關文章

計算目標檢測和語義分割的PR

需求描述 實際工作中&#xff0c;相比于mAP項目更加關心的是特定閾值下的precision和recall結果&#xff1b;由于本次的GT中除了目標框之外還存在多邊形標注&#xff0c;為此&#xff0c;計算IoU的方式從框與框之間變成了mask之間&#xff1b; 本文的代碼適用于MMDetection下的…

Java Web 學習之路(2) —— 概念、SpringBoot + MyBatis(controller+service+mapper)開發流程與過程梳理

文章目錄 前言1. 常見的一些概念1.1 POJO&#xff08;Plain Ordinary Java Object 簡單Java對象&#xff09;1.2 DAO和Mapper 2. Java的三層架構2.1 包的層級結構2.2 交互層 controller&#xff08;用戶界面、網頁&#xff09;jsp文件2.3 業務處理層 service2.4 Mapper層 3. 注…

如何同步fork項目原倉庫的更新

最簡單粗暴的方法&#xff1a;把原來fork的倉庫刪了重新fork&#xff08;嘿嘿不過這顯然是不優雅的&#xff09; 那我們該怎么同步更新呢&#xff1f; 如何在 Github 網頁端同步更新&#xff1f; 進入你自己的 fork 過來的倉庫。點擊 “Pull requests” &#xff0c;如何點擊…

2024 年甘肅省職業院校技能大賽信息安全管理與評估賽項規程

2024 年甘肅省職業院校技能大賽高職學生組電子與信息大類信息安全管理與評估賽項規程 一、賽項名稱 賽項名稱&#xff1a;信息安全管理與評估 賽項類別&#xff1a;團體賽 賽項歸屬&#xff1a;電子與信息大類 二、競賽目的 極安云科專注技能競賽&#xff0c;包含網絡建設…

Python基礎——正則匹配中高階用法

1.正則使用變量匹配re.escape() re.escape() 是一個用于轉義正則表達式中特殊字符的函數。當我們需要使用變量構建正則表達式模式時&#xff0c;為了避免特殊字符對模式的解析產生影響&#xff0c;我們可以使用 re.escape() 函數來自動轉義這些特殊字符。 例如&#xff0c;如…

微信小程序css實現的聯系客服動畫樣式

一 、效果 二、代碼 wxml <view class"customer-service"><button class"btn" open-type"contact"></button><image class"pic" src"https://ts4.cn.mm.bing.net/th?idOIP-C.3SGSiRPuOU9uH5VNVOMPwgHaHa…

序列的Z變換(信號的頻域分析)

1. 關于Z變換 2. 等比級數求和 3. 特殊序列的Z變換 4. 因果序列/系統收斂域的特點 5. 例題

navigationBar頂部導航欄,兼容適配所有機型(附完整案例)

思路 隱藏原生樣式獲取膠囊按鈕、狀態欄相關數據以供后續計算根據不同機型計算出該機型的導航欄高度,進行適配編寫為導航欄公共組件使用組件1. 隱藏原生樣式 全局設置 "window": {"navigationStyle": "custom" }單個頁面設置 {"navigat…

免費的AI文案生成器有哪些?AI文案生成器排行榜

在當今數字化的時代&#xff0c;內容創作已成為許多行業不可或缺的一部分。為了滿足日益增長的創作需求&#xff0c;越來越多的人開始尋找能夠提高效率、同時保持原創性的解決方案。本文將專心分享一些優質的AI文案生成器。 AI文案生成器的需求 內容創作已經不再是傳統媒體和市…

高項備考葵花寶典-項目進度管理輸入、輸出、工具和技術(上,很詳細考試必過)

項目進度管理的目標是使項目按時完成。有效的進度管理是項目管理成功的關鍵之一&#xff0c;進度問題在項目生命周期內引起的沖突最多。 小型項目中&#xff0c;定義活動、排列活動順序、估算活動持續時間及制定進度模型形成進度計劃等過程的聯系非常密切&#xff0c;可以視為一…

C語言基礎

常量和常量表達式的區別 #define N 4;又是常量&#xff0c;又是常量表達式&#xff0c;其在編譯期預處理階段就會直接替換 const int M 5;只是常量&#xff0c;不是常量表達式 &#xff0c;其是存儲在一塊內存區域之內的&#xff0c;但是存儲的值不能改變 常量表達式&#xff…

【USB、串口、COM口、TTL、RS-232、RS-485區別詳解】

USB&#xff0c;串口&#xff0c;COM口&#xff0c;TTL&#xff0c;RS-232&#xff0c;RS-485區別詳解 1. USB&#xff0c;串口&#xff0c;COM口&#xff0c;TTL&#xff0c;RS-232&#xff0c;RS-485區別詳解2 USB轉TTL2 RS-232轉TTL3 USB4 UART5 STM32串口異步通訊需要定義的…

iOS——定位與地圖

平時在寫項目的時候可能會遇到需要使用定位服務的地方&#xff0c;比如說獲取位置和導航等。因此這里我會使用OC自帶的庫以及蘋果系統的地圖來獲取定位以及顯示在地圖上。 開始前的設置 在獲取定位前&#xff0c;需要在項目文件的info中添加兩個關鍵字&#xff0c;用于向用戶…

從零開始的C++(二十一)

C11 1.列表初始化&#xff1a; //允許以下代碼正確運行int a[]{1,2,3};//效果與int a[]{1,2,3}一致 即允許省略等于號。同時&#xff0c;允許用花括號對所有自定義類型和內置類型進行初始化&#xff0c;而非以前花括號只能對數組進行初始化。利用花括號對自定義類型初始化時…

LeetCode刷題--- 求根節點到葉節點數字之和

個人主頁&#xff1a;元清加油_【C】,【C語言】,【數據結構與算法】-CSDN博客 個人專欄&#xff1a;http://t.csdnimg.cn/ZxuNL http://t.csdnimg.cn/c9twt 前言&#xff1a;這個專欄主要講述遞歸遞歸、搜索與回溯算法&#xff0c;所以下面題目主要也是這些算法做的 我講述…

【ITK庫學習】使用itk庫進行圖像濾波ImageFilter:鄰域濾波

目錄 1、itkMeanImageFilter 均值濾波器2、itkMedianImageFilter 中值濾波器3、itkBinaryMedianImageFilter 二值中值濾波器4、擴展itkNeighborhood5、擴展itkNeighborhoodIterator6、擴展itkNeighborhoodOperator 領域濾波是一種信號處理方法&#xff0c;用于去除信號中的噪聲…

★560. 和為 K 的子數組(自己做出來了)

560. 和為 K 的子數組 前綴和的知識。 如果要求i~j下標之間的元素和&#xff0c;用前綴和的話&#xff0c;應該是b[j] - b[i-1]&#xff0c;i處的值也應該包括。 所以這個題&#xff0c;前綴和數組就要比原數組整體向后平移一個單元格&#xff0c;不然在求0~n的和的時候沒法取…

在python中安裝庫,會有conda安裝,也會有pip安裝,conda與pip的區別是什么?

文章目錄 一、Conda是什么&#xff1f;二、pip是什么&#xff1f;三、pip與conda的區別&#xff1a;總結 一、Conda是什么&#xff1f; Conda是一個開源的包管理系統&#xff0c;它是Anaconda公司為Python和其他編程語言開發的。它主要用于數據科學和機器學習領域&#xff0c;…

【Vue】日常錯誤總結(持續更新)

日常遇到的小問題匯總, 內容小篇幅少的就全放這里了, 內容多的會在Vue專欄單獨分享~ 目錄 【Q】 el-form-item值為 null 或 undefined顯示““ 【Q】dialog內組件數據刷新總是延遲慢一拍 問題背景描述 解決方案 代碼簡單模擬 JS 【Q】el-input 不能輸入的解決辦法 方法…

Educational Codeforces Round 156 (Rated for Div. 2)補題

Sum of Three 題目大意&#xff1a;將一個正整數n分成3個不同的正整數x,y,z,保證三個數都不能整除3&#xff0c;如果無法實現就輸出NO. 思路&#xff1a;這個題實際上特別簡單&#xff0c;我們可以發現當n比較大的時候&#xff0c;我們可以從中取1&#xff0c;然后第二個數也…