Leetcode 1028. 从先序遍历还原二叉树【二叉树遍历系列】

问题描述

我们从二叉树的根节点 root 开始进行深度优先搜索。

在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。

如果节点只有一个子节点,那么保证该子节点为左子节点。

给出遍历输出 S,还原树并返回其根节点 root。
在这里插入图片描述

输入:“1-2- -3- -4-5- -6- -7”
输出:[1,2,5,3,4,6,7]

解题报告

模拟先序遍历进行反序列化。
通过读取 当前元素所属 - 个数【该元素前面 - 的个数】 和 栈中元素个数 大小关系 比较得出是否应该回溯。

  • 当前元素所属 - 个数栈中元素个数 相等时,说明继续向左子树迭代,当前元素是栈顶元素的左子树
  • 当前元素所属 - 个数栈中元素个数 小时,说明该回溯了,将栈中元素弹出,直到 当前元素所属 - 个数栈中元素个数 相等,此时当前元素即为栈顶元素的右子树。
  • 当前元素所属 - 个数 不会比 栈中元素个数 大,因为 1)不回溯时,- 每增加一个,就有一个元素入栈,【字符串的第一个数字对应的 - 为零】;2)当前元素所属 - 个数栈中元素个数 小时才会回溯。

这道题有点像二叉树的反序列化 Leetcode 297. 二叉树的序列化和反序列化,但是如果不是在题目限制的情况下【如果节点只有一个子节点,那么保证孩子节点为左子节点】,我们仅根据这样的先序遍历还是无法确定一个二叉树的。

总是不会实现自己的思想,看到别人的代码才知道原来可以这样实现啊,这是一个大问题。

实现代码

class Solution {
public:
    TreeNode* recoverFromPreorder(string S) {
        stack<TreeNode*> path;
        int pos = 0;
        while (pos < S.size()) {
            int level = 0;
            while (S[pos] == '-') {
                ++level;
                ++pos;
            }
            int value = 0;
            while (pos < S.size() && isdigit(S[pos])) {
                value = value * 10 + (S[pos] - '0');
                ++pos;
            }

            TreeNode* node = new TreeNode(value);
            if (level == path.size()) {
                if (!path.empty()) {
                    path.top()->left = node;
                }
            }
            else {
                // 当前节点的层数比栈中节点还要长,则说明需要开始回溯
                while (level != path.size()) path.pop();
                path.top()->right = node;
            }
            path.push(node);
        }

        while (path.size() > 1) {
            cout<<path.top()->val<<" ";
            path.pop();
        }
        return path.top();
    }
};

// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/recover-a-tree-from-preorder-traversal/solution/cong-xian-xu-bian-li-huan-yuan-er-cha-shu-by-leetc/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考资料

[1] Leetcode 1028. 从先序遍历还原二叉树
[2] 官方题解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章