【LeetCode】114. 二叉树展开为链表

104 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

题目

给你二叉树的根结点 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

题解

思路

首先,对于前序遍历,所以最右边的结点一定在链表的最后。

对于每一棵子树(设当前子树的根节点为root),我们要做如下三点:

  • 左子树前序遍历后的最后一个节点(即root.left的返回值l)的右指针指向root的右子树
  • root的右指针指向root的左子树,因为经过上一步操作右子树的节点已经存在于左子树上。
  • root的左指针赋为空
  • 之后要考虑的一个问题就是我们遍历到某个节点时如何确定其返回值:
  • 因为对于每一棵子树,其左子树的返回值的右指针指向右子树,所以返回值必定等于当前子树前序遍历后最右边的节点
  • 所以每次优先返回右子树的遍历结果
  • 如果右子树不存在,则返回左子树
  • 如果都不存在,返回当前节点

代码

# 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.
        """
        def dfs(root):
            if not root: return None
            l = dfs(root.left)
            r = dfs(root.right)
            if l:
                l.right = root.right
                root.right = root.left
                root.left = None
            if r: return r
            if l: return l
            return root 
        dfs(root)

结语

业精于勤,荒于嬉;行成于思,毁于随。