- 二叉树展开为链表
原始题目链接:https://leetcode.cn/problems/flatten-binary-tree-to-linked-list/
给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
解题思路:
一种使用O(n)的存储空间,按照先序遍历将二叉树遍历的节点存储到数组中,然后遍历数组中的节点,将节点前后链接起来。第二种方法是不使用额外的存储空间,通过分析,发现如果当前节点存在左子树,那么当前节点的下一个节点是左子树的根节点,当前节点的右子树是在左子树遍历完后,才开始遍历,所以左子树的最后一个节点指向当前节点的右子树的第一个节点。
代码实现:
解法1:
# 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:
# 存储先序遍历的节点
node_array = []
# 先序遍历二叉树
def dfs(self, root):
if root:
self.node_array.append(root)
self.dfs(root.left)
self.dfs(root.right)
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.dfs(root)
size = len(self.node_array)
for i in range(1, size):
# 前驱节点和后继节点
pre, cur = self.node_array[i - 1], self.node_array[i]
pre.right = cur
pre.left = None
解法2:
# 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.
"""
cur = root
while cur:
# 如果当前节点左子树不为空
if cur.left:
cur_pre = cur_next = cur.left
# 找当前节点左子树的最右边的节点
while cur_pre.right:
cur_pre = cur_pre.right
# 将当前节点的左子树的最右侧节点的right指针指向当前节点的右子树的根节点
cur_pre.right = cur.right
# 将当前节点的left指针置空(题目要求)
cur.left = None
# 将当前节点right指针向左子树的根节点
cur.right = cur_next
# 继续遍历下一个节点
cur = cur.right
参考文献:
https://leetcode.cn/problems/flatten-binary-tree-to-linked-list/solution/er-cha-shu-zhan-kai-wei-lian-biao-by-leetcode-solu/