1. 题目
给定一棵二叉树的根结点 root
,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode
,其中right
子指针指向链表中下一个结点,而左子指针始终为null
。 - 展开后的单链表应该与二叉树 前序遍历 顺序相同。
1.1 示例
- 示例 1 1 1 :
- 输入:
root = [1, 2, 5, 3, 4, null, 6]
- 输出:
[1, null, 2, null, 3, null, 4, null, 5, null, 6]
- 示例 2 2 2 :
- 输入:
root = []
- 输出:
[]
- 示例 3 3 3 :
- 输入:
root = [0]
- 输出:
[0]
1.2 说明
- 来源: 力扣(LeetCode)
- 链接: https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
1.3 限制
- 树中结点数在范围 [ 0 , 2000 ] [0,\textit{ }2000] [0, 2000] 内;
-100 <= Node.val <= 100
。
1.4 进阶
你可以使用原地算法( O ( 1 ) O(1) O(1) 额外空间)展开这棵树吗?
2. 解法一(前序遍历)
2.1 分析
本题的题干提示的非常明确,即展开后的单链表应该与二叉树 前序遍历 顺序相同,故最简单的方式就是先通过前序遍历得到所有结点的 val
值,然后再依次使用 TreeNode
创建结点并连接成单链表。
2.2 解答
from json import dumps
from typing import List
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, tree: List[int]):
if not root:
return
tree.append(root.val)
self._flatten(root.left, tree)
self._flatten(root.right, tree)
def flatten(self, root: TreeNode) -> None:
tree = []
self._flatten(root, tree)
if not root:
return
size = len(tree)
node = root
root.left = None
for i in range(1, size):
node.right = TreeNode(tree[i])
node = node.right
def main():
node6 = TreeNode(6)
node5 = TreeNode(4)
node4 = TreeNode(3)
node3 = TreeNode(5, left=None, right=node6)
node2 = TreeNode(2, left=node4, right=node5)
node1 = TreeNode(1, left=node2, right=node3)
root = node1
sln = Solution()
sln.flatten(root)
tree = []
def preorder_traverse(flattened_root: TreeNode):
if not flattened_root:
tree.append(None)
return
tree.append(flattened_root.val)
preorder_traverse(flattened_root.left)
preorder_traverse(flattened_root.right)
preorder_traverse(root)
print(dumps(tree)) # [1, null, 2, null, 3, null, 4, null, 5, null, 6, null, null]
if __name__ == '__main__':
main()
实际上,我们并不需要在前序遍历之后再重新创建结点,而是可以在前序遍历时就将结点保存起来而非保存结点的 val
值:
from json import dumps
from typing import List
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, tree: List[TreeNode]):
if not root:
return
tree.append(root)
self._flatten(root.left, tree)
self._flatten(root.right, tree)
def flatten(self, root: TreeNode) -> None:
tree = []
self._flatten(root, tree)
if not root:
return
size = len(tree)
node = root
for i in range(1, size):
node.right = tree[i]
node.left = None
node = node.right
2.3 复杂度
- 时间复杂度: O ( n ) O(n) O(n) ;
- 空间复杂度: O ( n ) O(n) O(n) 。