給你二叉樹的根結點 root ,請你將它展開爲一個單鏈表:
展開後的單鏈表應該同樣使用 TreeNode ,其中 right 子指針指向鏈表中下一個結點,而左子指針始終爲 null 。
展開後的單鏈表應該與二叉樹 先序遍歷 順序相同。
示例 1:
輸入:root = [1,2,5,3,4,null,6]
輸出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:
輸入:root = []
輸出:[]
示例 3:
輸入:root = [0]
輸出:[0]
提示:
樹中結點數在範圍 [0, 2000] 內
-100 <= Node.val <= 100
進階:你可以使用原地算法(O(1) 額外空間)展開這棵樹嗎?
【分析】
方法一:後序遍歷、遞歸
依據二叉樹展開爲鏈表的特點,使用後序遍歷完成展開。
# 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 helper(root): if root is None: return helper(root.left) # 遞歸左子樹 helper(root.right) # 遞歸右子樹 # 後序遍歷 if root.left != None: pre = root.left # 令 pre 指向左子樹 while pre.right: pre = pre.right # 找到左子樹中的最右節點
# 令左子樹的最右節點的右子樹,指向根節點的右子樹 pre.right = root.right
# 令根節點的右子樹指向根節點的左子樹 root.right = root.left
root.left = None # 置空根節點左子樹 helper(root)
解法二: 非遞歸,不使用輔助空間及全局變量
前面的遞歸解法實際上也使用了額外的空間,因爲遞歸需要佔用額外空間。下面的解法無需申請棧,也不用全局變量,是真正的 In-Place 解法
# 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. """ while (root != None): if root.left != None: most_right = root.left while most_right.right != None: most_right = most_right.right most_right.right = root.right root.right = root.left root.left = None root = root.right return
本人目前覺得第二種非遞歸方法更好理解,可以手動通過例子,逐行執行上述代碼,即可對該思路理解更加清晰。