Leetcode-889-根据前序和后序遍历构造二叉树-c++

题目详见https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-postorder-traversal/

回顾一下之前博客里的知识点:

补充一道牛客上面的面试题https://www.nowcoder.com/questionTerminal/597f173686fe4cc390e8ff8c47129acb

以下哪种遍历序列的组合可以还原二叉树(B)
A.先序遍历序列和后序遍历序列
B.后序遍历序列和中序遍历序列
C.先序遍历序列和层序遍历序列
D.中序遍历序列和层序遍历序列

中+前/后任意一个都可以还原二叉树

这里是前+后,因此题目中明确表示,如果有多种结果,输出任意一个.

知识点补充-内嵌匿名函数goto知识点

function<TreeNode *(int, int, int, int)> dfs = [&](int preLeft, int preRight, int postLeft, int postRight) -> TreeNode * {......}

普通函数定义是将函数放在外层作用域中,此函数定义是将函数定义在其他函数内部,即内嵌匿名函数。
普通函数有名称,可以单独调用;而内嵌匿名函数没有名称,只能在定义它的函数内部调用

注释代码

class Solution {
public:
    TreeNode *constructFromPrePost(vector<int> &preorder, vector<int> &postorder) {
        int n = preorder.size();
        unordered_map<int, int> postMap;
        // 这里如果postorder = [4,5,2,6,7,3,1]
        for (int i = 0; i < n; i++) {
            postMap[postorder[i]] = i;
        }
        // 则postMap:{[1] = 6, [3] = 5, [7] = 4, [6] = 3, [2] = 2, [5] = 1, [4] = 0}
        function<TreeNode *(int, int, int, int)> dfs = [&](int preLeft, int preRight, int postLeft, int postRight) -> TreeNode * {
            if (preLeft > preRight) {
                return nullptr;
            }
            int leftCount = 0;
            if (preLeft < preRight) {
            	// 左子树的节点个数 =
            	// 前序遍历左节点的下一个节点(左子树的根;如有)在后序遍历中的位置(也就是左子树在后序遍历中的最右侧结点,因为左-右-根)
            	// - postleft(左子树在后序遍历中的最左侧结点)
            	// + 1(别问我为什么+1)
                leftCount = postMap[preorder[preLeft + 1]] - postLeft + 1;
            }
            return new TreeNode(preorder[preLeft],
            	// 递归左子树
                dfs(preLeft + 1, preLeft + leftCount, postLeft, postLeft + leftCount - 1),
                // 递归右子树
                dfs(preLeft + leftCount + 1, preRight, postLeft + leftCount, postRight - 1));
        };
        return dfs(0, n - 1, 0, n - 1);
    }
};
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值