106_从中序与后序遍历序列构造二叉树

简介: 106_从中序与后序遍历序列构造二叉树

106_从中序与后序遍历序列构造二叉树

 

package 二叉树.BT;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
 * https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
 * @author Huangyujun
 *
 */
public class _106_从中序与后序遍历序列构造二叉树 {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {
        }
        TreeNode(int val) {
            this.val = val;
        }
        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}
/**
* 大佬的代码启发:想要使用递归(当直接使用不了题目给的参数是,可以自己定义一个同名(参数自己定,然后不断的递归)),题意给的方法再调用该方法即可
** TreeNode buildTree(int[] inorder, int[] postorder) 这个方法是题目本身
*  public TreeNode buildTree(int is, int ie, int ps, int pe) 这个方法是自定义的
*  使用递归突破点:什么时候跳出return:往往看传入的参数的关系(当参数变化到不合理是即退出)
*/
class Solution {
    HashMap<Integer,Integer> memo = new HashMap<>();
    int[] post;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i = 0;i < inorder.length; i++) memo.put(inorder[i], i);
        post = postorder;
        TreeNode root = buildTree(0, inorder.length - 1, 0, post.length - 1);
        return root;
    }
//一个树:【中序遍历时的范围】【后序遍历的范围】
//该过程 获取到根,然后才划分出两颗树(左子树、右子树)
    public TreeNode buildTree(int is, int ie, int ps, int pe) {
        if(ie < is || pe < ps) return null;
        int root = post[pe];
        int ri = memo.get(root);
        TreeNode node = new TreeNode(root);
        node.left = buildTree(is, ri - 1, ps, ps + ri - is - 1);
        node.right = buildTree(ri + 1, ie, ps + ri - is, pe - 1);
        return node;
    }
}
/**
 * 官网的思考角度即我的思考角度:尤其是:(参数是一棵树范围,然后先右子树再左子树):
 * 只是我还没有将思想更加清晰的转化成:树【范围用 中序表示】,后序最后一个元素用来取根结点(这也是为什么先右子树再左子树),因为后序是 左右 根, 右子树离最后一个位置最近
// 下标减一
    post_idx--;
    // 构造右子树
    root.right = helper(index + 1, in_right);
    // 构造左子树
    root.left = helper(in_left, index - 1);
 * @author Huangyujun
 *
 */
class Solution2 {
    int post_idx;
    int[] postorder;
    int[] inorder;
    Map<Integer, Integer> idx_map = new HashMap<Integer, Integer>();
    public TreeNode helper(int in_left, int in_right) {
        // 如果这里没有节点构造二叉树了,就结束
        if (in_left > in_right) {
            return null;
        }
        // 选择 post_idx 位置的元素作为当前子树根节点
        int root_val = postorder[post_idx];
        TreeNode root = new TreeNode(root_val);
        // 根据 root 所在位置将中序分成左右两棵子树
        int index = idx_map.get(root_val);
        // 下标减一
        post_idx--;
        // 构造右子树
        root.right = helper(index + 1, in_right);
        // 构造左子树
        root.left = helper(in_left, index - 1);
        return root;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        this.postorder = postorder;
        this.inorder = inorder;
        // 从后序遍历的最后一个元素开始
        post_idx = postorder.length - 1;
        // 建立(元素,下标)键值对的哈希表
        int idx = 0;
        for (Integer val : inorder) {
            idx_map.put(val, idx++);
        }
        return helper(0, inorder.length - 1);
    }
}
目录
相关文章
|
5月前
|
Java C++ 索引
leetcode-106:从中序与后序遍历序列构造二叉树
leetcode-106:从中序与后序遍历序列构造二叉树
44 0
|
12月前
【LeetCode】105. 从前序与中序遍历序列构造二叉树
题目描述: 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例:
55 0
21_从中序与后序遍历序列构造二叉树
21_从中序与后序遍历序列构造二叉树
|
5月前
|
C++ 索引 Python
leetcode-105:从前序与中序遍历序列构造二叉树
leetcode-105:从前序与中序遍历序列构造二叉树
43 0
|
10月前
|
C++ 索引
从中序与后序遍历序列构造二叉树(C++实现)
从中序与后序遍历序列构造二叉树(C++实现)
66 1
|
10月前
|
C++ 索引
从前序与中序遍历序列构造二叉树(C++实现)
从前序与中序遍历序列构造二叉树(C++实现)
74 1
|
C++
力扣 - 106、从中序与后序遍历序列构造二叉树
力扣 - 106、从中序与后序遍历序列构造二叉树
96 0
|
机器学习/深度学习
每日三题-对称二叉树、从前序与中序遍历序列构造二叉树、不同的二叉搜索树
每日三题 对称二叉树 从前序与中序遍历序列构造二叉树 不同的二叉搜索树
88 4
每日三题-对称二叉树、从前序与中序遍历序列构造二叉树、不同的二叉搜索树
leetcode 106 从中序和后续遍历序列构造二叉树
leetcode 106 从中序和后续遍历序列构造二叉树
80 0
leetcode 106 从中序和后续遍历序列构造二叉树