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] 官方題解

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