从前序与中序遍历序列构造二叉树

本文介绍了一种通过前序和中序遍历来构建二叉树的方法。利用递归思想,通过定位根节点,划分左右子树,最终实现二叉树的构建。

题目

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

3

/
9 20
/
15 7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        TreeNode root = buildTree(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
        return root;
    }

    public TreeNode buildTree(int[] preorder, int[] inorder, int preStart,
            int preEnd, int inStart, int inEnd){

        //做结束判断
        if(preStart > preEnd || inStart > inEnd){
            return null;
        }

        //初始化root
        TreeNode root = new TreeNode(preorder[preStart]);
        //寻找root在inorder中的位置,方便做切割,并且递归
        int inRoot = 0;
        for(int i = 0; i < inorder.length; i ++){
            if(root.val == inorder[i]){
                inRoot = i;
                break;
            }
        }
        
        //左子树的长度
        int leftLen = inRoot  - inStart;
        root.left = buildTree(preorder, inorder, preStart + 1, preStart + leftLen,
                                inStart, inRoot - 1);
        root.right = buildTree(preorder, inorder, preStart + leftLen + 1, preEnd, 
                                inRoot + 1, inEnd);

        return root;
        
    }
}

分析

这里又是一个二叉树递归的问题,题目给的buildTree的变量其实是在误导读者,这里需要自己重新来构造一个,起点和终点的选择很重要。

总结

递归问题分四步走:
1)如果不递归,正常的一个初始流程怎么写,就是n = 1的写法
2)进行递归,选择循环的点,像本题中的preStart,preEnd,inStart,inEnd。就是寻找n->n+1
3)结束的操作是什么,就是递归的结束点是什么,比如本题的

if(preStart > preEnd || inStart > inEnd){
            return null;
        }

就是最后如何回归到n = 1并结束递归这个点
4)递归要做的操作是什么,比如本题是为了构造树,

TreeNode root = new TreeNode(preorder[preStart]);

还有这条语句插入的位置很重要,在递归调用前就是前序,在后面就是后序,很显然本例是前序调用。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值