Given the root
of a binary tree, flatten the tree into a "linked list":
- The "linked list" should use the same
TreeNode
class where theright
child pointer points to the next node in the list and theleft
child pointer is alwaysnull
. - The "linked list" should be in the same order as a pre-order traversal of the binary tree.
Example 1:
Input: root = [1,2,5,3,4,null,6] Output: [1,null,2,null,3,null,4,null,5,null,6]
Example 2:
Input: root = [] Output: []
Example 3:
Input: root = [0] Output: [0]
Constraints:
- The number of nodes in the tree is in the range
[0, 2000]
. -100 <= Node.val <= 100
Follow up: Can you flatten the tree in-place (with O(1)
extra space)?
题目要求把一棵二叉树转换成以根节点为头节点的链表,但是不能新创链表节点,要仍然以二叉树的节点为链表的节点,即二叉树节点的右子节点为链表节点的next,二叉树节点的左子节点指向空。另外还要求链表的节点顺序是按照二叉树前序遍历的顺序。
既然要求是二叉树前序遍历的顺序,那就按照前序遍历算法来按顺序处理每个节点,有递归和迭代两种方法。前序遍历算法可参考105. Construct Binary Tree from Preorder and Inorder Traversal。
递归法:前序遍历的顺序是先根节点,再左子树和右子树。如果左子树和右子树都已经被转换成了链表,那就把根节点与左子链表相连,再与右子链表相连就构成了一个完整的链表。这种思路用递归法来实现最简单直观。
实现一个递归函数,输入是根节点,输出是转换成链表后的头节点和尾节点,递归终止条件是当输入的根节点为空。根节点就是链表的头节点,分别递归处理左子树和右子树,分别返回的是左子树链表的头尾节点和右子树链表的头尾节点,然后链接根节点和两个链表,根节点的left指向空,right指向左子树链表头。在处理时需要注意判断左子树链表是否为空,如果为空,则根节点right指向右子树链表头。
# 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: Optional[TreeNode]) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.helper(root)
def helper(self, root):
if not root:
return None, None
lhead, ltail = self.helper(root.left)
rhead, rtail = self.helper(root.right)
root.left = None
end = root
if lhead:
end.right = lhead
end = ltail
if rhead:
end.right = rhead
end = rtail
return root, end