给你二叉树的根结点 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)
额外空间)展开这棵树吗?
一解
使用 dfs,递归的把左子树转换为右子树,并将原来右子树放其后面。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root: return
right_child = self.flatten(root.right)
# 把整理好的左子树根节点放到 root 的右子树,记为 l1
root.right = self.flatten(root.left)
root.left = None
# 若 l1 为空,则将右子树直接接上
if not root.right:
root.right = right_child
# 若 l1 不为空,找最 l1 的最边节点
else:
node = root.right
while node.right:
node = node.right
node.right = right_child
return root
- 时间复杂度 O(n):n 为树的高度,最坏情况,该树只有左子树。
- 空间复杂度 O(n):n 为树的高度,最坏情况,该树只有左子树,需要递归到最左结点。
二解
使用迭代法,设当前结点为 cur:
- 若 cur 存在左子结点:
- 将 cur 的右结点作为 cur 的「第一个左子结点下的最右结点的右孩子」。
- 将 cur 的第一个左子结点放到 cur 的右子结点(左子树 l1 变为右子树,cur.right 会继续处理 l1)。
- 将 cur 左子结点置空。
- 令 cur 指向右孩子。
- 重复上述过程。
将 predecessor 和 nxt
class Solution:
def flatten(self, root: TreeNode) -> None:
curr = root
while curr:
if curr.left:
predecessor = nxt = curr.left
while predecessor.right:
predecessor = predecessor.right
predecessor.right = curr.right
curr.left = None
curr.right = nxt
curr = curr.right
- 时间复杂度 O(n):n 为结点数量。
- 空间复杂度 O(1)。