一開始寫的:
#
## [114] 二叉樹展開為鍊錶
## definition for a binary tree node.
# class treenode:
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class solution:
def flatten(self, root: treenode) -> none:
"""do not return anything, modify root in-place instead.
"""def preorder(node):
if not node:
return
preorder(node.left)
preorder(node.right)
if not root:
return
temp=
preorder(root)
for i in range(len(temp)-1):
temp[i].left=none
temp[i].right=temp[i+1]
temp[len(temp)-1].left=none
temp[len(temp)-1].right=none
能通過,但看別人的題解發現題幹寫了「原地」,我這個申請了額外的陣列儲存前序遍歷的節點顯然不對了。然後看別人的後序做法又自己寫。乙個關鍵問題,為什麼不能用中序或前序:因為題幹最後要求的順序是前序:即中,左,右,在考察某特定節點時,將其左右子樹全部處理完畢之前不能將該節點與其左右子樹的連線改掉(想了半天),所以只有後序遍歷的順序是:左,右,中,在遍歷到中節點的時候,左右子樹已經處理好,此時可以改動中節點與左右子樹的連線了。
下面是參考題解自己寫的後序**,思路就是先處理左右子樹,然後處理根節點。根節點右指標連線左子樹最右元素p(即前序前繼),p右指標再連線根節點原右子樹,這樣就是中,左,右的前序順序了。
# definition for a binary tree node.
# class treenode:
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class solution:
def flatten(self, root: treenode) -> none:
"""do not return anything, modify root in-place instead.
"""def func(node):
if not node:
return
func(node.left)
func(node.right)
p=node.left
while p and p.right:
p=p.right
if p:
node_right=node.right
node.right=node.left
node.left=none
p.right=node_right
func(root)
又寫了個迭代的:先處理右子樹成一條鍊錶,再處理左子樹成一條鍊錶,然後和根節點連起來。。
class solution:
def flatten(self, root: treenode) -> none:
"""do not return anything, modify root in-place instead.
"""if not root:
return
le,ri=none,none
if root.left:
le=root.left
if root.right:
ri=root.right
while ri and (ri.left or ri.right):
if not ri.left:
ri=ri.right
else:
p=ri.left
while p.right:
p=p.right
ri_right=ri.right
ri.right=ri.left
p.right=ri_right
ri.left=none
ri=ri.right
while le and (le.left or le.right):
if not le.left:
le=le.right
else:
p=le.left
while p.right:
p=p.right
le_right=le.right
le.right=le.left
p.right=le_right
le.left=none
le=le.right
if le:
le.right=root.right
root.right=root.left
root.left=none
然後我發現:我為啥要分左右子樹再串起來??明明從根節點乙個while迴圈就行了,腦子抽了!!
class solution:
def flatten(self, root: treenode) -> none:
"""do not return anything, modify root in-place instead.
"""if not root:
return
x=root
while x and (x.left or x.right):
if not x.left:
x=x.right
else:
p=x.left
while p.right:
p=p.right
x_right=x.right
x.right=x.left
p.right=x_right
x.left=none
x=x.right
114 二叉樹展開為鍊錶
首先是原地演算法的定義 演算法原地工作的含義是指不需要任何額外的輔助,演算法所需要的輔助空間不隨著問題的規模而變化,是乙個確定的值。通過觀察示例可以知道,我們可以猜想,大方向是前序遍歷。第一種思路 dfs。設定乙個全域性的指標 這種做法有點脫離原地演算法,因為多開闢了乙個指標變數 核心思想是拿到乙個...
114 二叉樹展開為鍊錶
給定乙個二叉樹,原地將它展開為鍊錶。例如,給定二叉樹 1 2 5 3 4 6將其展開為 1 2 3 4 5 6思路 從題目可以看出來要求先根遍歷。從根節點開始出發,先檢測其左子結點是否存在 1 找到左子結點最後面的右子節點 如果沒有,就是左子節點本身 2 將根節點和其右子節點斷開,把原右子節點連到原...
114 二叉樹展開為鍊錶
給定乙個二叉樹,原地將它展開為鍊錶。例如,給定二叉樹 1 2 5 34 6將其展開為 1 2 3 4 5 6我們發現,如果從最底層的結點開始,都把它的右孩子插入在左孩子的最後乙個結點處,然後再遞迴的調整結果來的這棵樹,則整棵樹滿足題意。為啥?因為最左下的子樹我們都調整好了。也可以認為這是中序遍曆法。...