[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]
【問題描述】[中等]
根據一棵樹的前序遍歷與中序遍歷構造二叉樹。注意: 你可以假設樹中沒有重復的元素。例如,給出前序遍歷 preorder = [3,9,20,15,7] 中序遍歷 inorder = [9,3,15,20,7] 返回如下的二叉樹:3/ \9 20/ \15 7【解答思路】
1. 遞歸
先序遍歷的順序是根節點,左子樹,右子樹。中序遍歷的順序是左子樹,根節點,右子樹。
只需要根據先序遍歷得到根節點,然后在中序遍歷中找到根節點的位置,它的左邊就是左子樹的節點,右邊就是右子樹的節點。
時間復雜度:O(N) 空間復雜度:O(N)
HashMap優化
public TreeNode buildTree(int[] preorder, int[] inorder) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length, map); }private TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end,HashMap<Integer, Integer> map) {if (p_start == p_end) {return null;}int root_val = preorder[p_start];TreeNode root = new TreeNode(root_val);int i_root_index = map.get(root_val);int leftNum = i_root_index - i_start;root.left = buildTreeHelper(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index, map);root.right = buildTreeHelper(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end, map);return root; }2. 迭代 棧
用一個棧保存已經遍歷過的節點,遍歷前序遍歷的數組,一直作為當前根節點的左子樹,直到當前節點和中序遍歷的數組的節點相等了,那么我們正序遍歷中序遍歷的數組,倒著遍歷已經遍歷過的根節點(用棧的 pop 實現),找到最后一次相等的位置,把它作為該節點的右子樹。
代碼細節
- 用一個棧保存已經遍歷的節點
- 用 curRoot 保存當前正在遍歷的節點
時間復雜度:O(N) 空間復雜度:O(N)
【總結】
1.前中后序遍歷變化的是[中]的位置,左到右的順序不改變
- 前序遍歷 中左右
- 中序遍歷 左中右
- 后續遍歷 左右中
2.還原二叉樹 借助HashMap or copyOfRange
根據前序和后序遍歷構造二叉樹
[Leetcode][第889題][JAVA][根據前序和后序遍歷構造二叉樹][分治][遞歸]
前序+中序遍歷可畫出原二叉樹
[Leedcode][JAVA][第105題][從前序與中序遍歷序列構造二叉樹][棧][遞歸][二叉樹]
后續+中序遍歷可畫出原二叉樹
[Leetcode][第106題][JAVA][ 從中序與后序遍歷序列構造二叉樹][分治][遞歸]
3. 多畫圖 寫寫寫 遍歷代碼 手撕變量 大腦保持清醒
轉載鏈接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–22/
總結
以上是生活随笔為你收集整理的[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pat-1057 Stack 树状数组+
- 下一篇: [Leedcode][JAVA][第39