首页 > 其他分享 >leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal 根据前序和后

leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal 根据前序和后

时间:2022-10-06 16:57:02浏览次数:73  
标签:Binary 遍历 Preorder preorder int 前序 preL postL postorder

一、题目大意

给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。

如果存在多个答案,您可以返回其中 任何 一个。

示例 1:

输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]

输出:[1,2,3,4,5,6,7]

示例 2:

输入: preorder = [1], postorder = [1]

输出: [1]

提示:

  • 1 <= preorder.length <= 30
  • 1 <= preorder[i] <= preorder.length
  • preorder 中所有值都 不同
  • postorder.length == preorder.length
  • 1 <= postorder[i] <= postorder.length
  • postorder 中所有值都 不同
  • 保证 preorder 和 postorder 是同一棵二叉树的前序遍历和后序遍历

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

二、解题思路

先序遍历顺序是根左右,后序遍历顺序是 左右根,要建立树,肯定要从根节点开始创建,然后再创建左右子节点,根据先序和后序的特点,根节点的位置是固定的,即是先序遍历的第一个,又是后序遍历的最后一个,知道了根节点位置,我们需要分隔左右子树的区间。

先序遍历:[1][2,4,5][3,6,7]

后序遍历:[4,5,2][6,7,3][1]

先序和后序中各自左子树区间长度相等,数字顺序可能不同,通过观察2和3分别是左子树和右子树的根节点(先序的头后序的尾),可以根据其来定位左右子树区间的位置范围了,拆分数组,可以用双指针来指向子区间的开头和末尾。用preL和preR分别代表左子树区间的开头和结尾位置,postL和postR表示右子树区间的开头和结尾位置,那么若preL大于preR或者postL大于postR的时候,说明已经不存在子树区间,直接返回空指针。然后要先新建当前树的根节点,就通过pre[preL]取到即可,接下来要找左子树的根节点在post中的益,最简单的方法就是遍历post中的区间[postL, postR],找到其位置idx,然后根据这个idx就可以算出左子树区间长度为len = (idx - postL) + 1,那么pre数组中左子树区间为[preL+1, preL+len],右子树区间为[preL+1+len, preR],同理,post数组中左子树区间为[postL, idx],右子树区间为[idx+1, postR-1]。知道了这些信息,就可以调用递归函数了。

三、解题方法

3.1 Java实现

public class Solution {
    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        return helper(preorder, 0, preorder.length - 1, postorder, 0, postorder.length - 1);
    }

    TreeNode helper(int[] pre, int preL, int preR, int[] post, int postL, int postR) {
        if (preL > preR || postL > postR) {
            return null;
        }
        TreeNode node = new TreeNode(pre[preL]);
        if (preL == preR) {
            return node;
        }
        int idx = -1;
        for (idx = postL; idx <= postR; idx++) {
            if (pre[preL + 1] == post[idx]) {
                break;
            }
        }
        node.left = helper(pre, preL + 1, preL + 1 + (idx - postL), post, postL, idx);
        node.right = helper(pre, preL + 1 + (idx - postL) + 1, preR, post, idx + 1, postR - 1);
        return node;
    }
}

四、总结小记

  • 2022/10/6 今天今天有点冷

标签:Binary,遍历,Preorder,preorder,int,前序,preL,postL,postorder
From: https://www.cnblogs.com/okokabcd/p/16757957.html

相关文章