536. Construct Binary Tree from String
536. Construct Binary Tree from String
做這題之前可以先完成 606. Construct String from Binary Tree 。
這題的基礎題目是要將一棵樹字串化,用到的方法是後序遍歷,到了這個題目,目標在於要分析出一串字串的結構,進而不斷地頗析其子樹,而子樹的結構的樣式為:
子樹 = 根節點(左子樹)(右子樹)
從題目的結構來看,我們會優先知道的節點資訊,反而是根節點,所以這個題目就變成了前序遍歷的題目了。
接下來都是看要怎麼將字串處理成我們需要的節點資訊
取得根節點的值
觀察題目,這個題目的根節點,不會有括號來影響,只是要注意的是負號,但是對 Python 來說,負號是可以透過 int 的 API 直接將字串轉換成數字的,所以我們用一個 Loop 來去找到這個數字的開頭與結尾,這樣我們就可以知道根節點的值是什麼了
end = begin
if begin == len(s):
return None
while end < len(s) and (s[end].isdigit() or s[end] == '-'):
end += 1
root = TreeNode(int(s[begin:end]))
處理左右子樹
處理完根節點後,就可以先處理左子樹,再處理右子樹,如果我們已經處理完根節點了,剩下的事情就很好處理了因為
(左子樹)(右子樹)可以看成這樣
左子樹 = 左子樹的根節點(左子樹的左子樹)(左子樹的右子樹)
右子樹 = 右子樹的根節點(右子樹的左子樹)(右子樹的右子樹)
(左子樹)(右子樹)==
(左子樹的根節點(左子樹的左子樹)(左子樹的右子樹))(右子樹的根節點(右子樹的左子樹)(右子樹的右子樹))
所以我們就可以用遞迴的關係,只要將左、右子樹去掉最外面的括號,就可以用同樣的遞迴方程式去解析該子樹,所以剩下的部分就是細心的處理左右子樹的字串,這裡會用到另一個題目的知識點,就是如何頗析括號: 20. Valid Parentheses。
在找到左、右子樹的開頭與結尾的括號的位置後,就可以將子樹的字串,遞迴的處理
begin = end
if end < len(s) and s[end] == '(':
stack = []
stack.append(s[end])
end += 1
while end < len(s) and stack:
if s[end] == '(':
stack.append(s[end])
if s[end] == ')':
stack.pop()
end += 1
root.left = traverse(s[begin+1:end-1], 0)
begin = end
if end < len(s) and s[end] == '(':
stack = []
stack.append(s[end])
end += 1
while end < len(s) and stack:
if s[end] == '(':
stack.append(s[end])
if s[end] == ')':
stack.pop()
end += 1
root.right = traverse(s[begin+1:end-1], 0)
最後的結果
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def str2tree(self, s: str) -> Optional[TreeNode]:
def traverse(s, begin):
end = begin
if begin == len(s):
return None
while end < len(s) and (s[end].isdigit() or s[end] == '-'):
end += 1
root = TreeNode(int(s[begin:end]))
begin = end
if end < len(s) and s[end] == '(':
stack = []
stack.append(s[end])
end += 1
while end < len(s) and stack:
if s[end] == '(':
stack.append(s[end])
if s[end] == ')':
stack.pop()
end += 1
root.left = traverse(s[begin+1:end-1], 0)
begin = end
if end < len(s) and s[end] == '(':
stack = []
stack.append(s[end])
end += 1
while end < len(s) and stack:
if s[end] == '(':
stack.append(s[end])
if s[end] == ')':
stack.pop()
end += 1
root.right = traverse(s[begin+1:end-1], 0)
return root
return traverse(s, 0)