[LeetCode] 536. Construct Binary Tree from String 從字符串創建二叉樹


 

You need to construct a binary tree from a string consisting of parenthesis and integers.

The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure.

You always start to construct the left child node of the parent first if it exists.

Example:

Input: "4(2(3)(1))(6(5))"
Output: return the tree root node representing the following tree:

       4
     /   \
    2     6
   / \   / 
  3   1 5   

 

Note:

  1. There will only be '('')''-' and '0' ~ '9' in the input string.
  2. An empty tree is represented by "" instead of "()".

 

這道題讓我們根據一個字符串來創建一個二叉樹,其中結點與其左右子樹是用括號隔開,每個括號中又是數字后面的跟括號的模式,這種模型就很有遞歸的感覺,所以我們當然可以使用遞歸來做。首先我們要做的是先找出根結點值,我們找第一個左括號的位置,如果找不到,說明當前字符串都是數字,直接轉化為整型,然后新建結點返回即可。否則的話從當前位置開始遍歷,因為當前位置是一個左括號,我們的目標是找到與之對應的右括號的位置,但是由於中間還會遇到左右括號,所以我們需要用一個變量 cnt 來記錄左括號的個數,如果遇到左括號,cnt 自增1,如果遇到右括號,cnt 自減1,這樣當某個時刻 cnt 為0的時候,我們就確定了一個完整的子樹的位置,那么問題來了,這個子樹到底是左子樹還是右子樹呢,我們需要一個輔助變量 start,當最開始找到第一個左括號的位置時,將 start 賦值為該位置,那么當 cnt 為0時,如果 start 還是原來的位置,說明這個是左子樹,我們對其調用遞歸函數,注意此時更新 start 的位置,這樣就能區分左右子樹了,參見代碼如下:

 

解法一:

class Solution {
public:
    TreeNode* str2tree(string s) {
        if (s.empty()) return NULL;
        auto found = s.find('(');
        int val = (found == string::npos) ? stoi(s) : stoi(s.substr(0, found));
        TreeNode *cur = new TreeNode(val);
        if (found == string::npos) return cur;
        int start = found, cnt = 0;
        for (int i = start; i < s.size(); ++i) {
            if (s[i] == '(') ++cnt;
            else if (s[i] == ')') --cnt;
            if (cnt == 0 && start == found) {
                cur->left = str2tree(s.substr(start + 1, i - start - 1));
                start = i + 1;
            } else if (cnt == 0) {
                cur->right = str2tree(s.substr(start + 1, i - start - 1));
            }
        }
        return cur;
    }
};

 

下面這種解法使用迭代來做的,借助棧 stack 來實現。遍歷字符串s,用變量j記錄當前位置i,然后看當前遍歷到的字符是什么,如果遇到的是左括號,什么也不做繼續遍歷;如果遇到的是數字或者負號,那么我們將連續的數字都找出來,然后轉為整型並新建結點,此時我們看 stack 中是否有結點,如果有的話,當前結點就是棧頂結點的子結點,如果棧頂結點沒有左子結點,那么此結點就是其左子結點,反之則為其右子結點。之后要將此結點壓入棧中。如果我們遍歷到的是右括號,說明棧頂元素的子結點已經處理完了,將其移除棧,參見代碼如下:

 

解法二:

class Solution {
public:
    TreeNode* str2tree(string s) {
        if (s.empty()) return NULL;
        stack<TreeNode*> st;
        for (int i = 0; i < s.size(); ++i) {
            int j = i;
            if (s[i] == ')') st.pop();
            else if ((s[i] >= '0' && s[i] <= '9') || s[i] == '-') {
                while (i + 1 < s.size() && s[i + 1] >= '0' && s[i + 1] <= '9') ++i;
                TreeNode *cur = new TreeNode(stoi(s.substr(j, i - j + 1)));
                if (!st.empty()) {
                    TreeNode *t = st.top();
                    if (!t->left) t->left = cur;
                    else t->right = cur;
                }
                st.push(cur);
            }
        }
        return st.top();
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/536

 

類似題目:

Construct String from Binary Tree

 

參考資料:

https://leetcode.com/problems/construct-binary-tree-from-string/

https://leetcode.com/problems/construct-binary-tree-from-string/discuss/100359/Java-stack-solution

https://leetcode.com/problems/construct-binary-tree-from-string/discuss/100355/Java-Recursive-Solution

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM