1. Job Roadmap
  2. Home
  3. Problem Set
  4. codenotelist
  5. Forum
  6. course
  7. Shore Share Sessions
  8. Record
  1. Login
  2. Sign Up
  3. Language
    1. English
    2. 한국어
    3. 简体中文
    4. 正體中文
    ZhContent TextSol AI分析

二叉树展开为单链表

问题分析

将一棵二叉树原地展开为一个单链表,链表节点顺序等于二叉树的先序遍历(根→左→右)。展开后每个节点的左指针必须为 null,右指针指向下一个节点。

解题思路

方法一(递归后序反向处理):

  • 使用递归函数返回当前子树展开后的“尾节点”。
  • 对于当前节点 root:先递归展开右子树,得到 rightTail;再递归展开左子树,得到 leftTail。

P4063.二叉树展开为链表

    1000ms Tried: 1575 Accepted: 518 Difficulty: 5 所属公司 : Hot100
    算法与标签>二叉树

前置知识(必读必做):LeetCode 104. 二叉树的最大深度-自底向上的DFS

在线刷题

给你二叉树的根结点 rootrootroot,请你将它展开为一个单链表:

  • 展开后的单链表仍然使用 TreeNode
  • right 指针指向链表中下一个节点,left 始终为 null
  • 链表顺序必须与二叉树先序遍历顺序相同

样例1

img

输入

1 2 5 3 4 null 6

输出

1 null 2 null 3 null 4 null 5 null 6

样例2

输入

0

输出

0

提示

  • 树中结点数在范围 [0,2000][0, 2000][0,2000] 内
  • −100<=Node.val<=100-100 <= Node.val <= 100−100<=Node.val<=100

方法一:自底向上的 DFS

受到LeetCode 104. 二叉树的最大深度中方法二:自底向上的DFS的启发,我们考虑拆分子问题:

当前节点展开结果 = 当前节点 + 左子树链 + 右子树链

例如样例1 : 从根节点开始,一个“自底向上”的想法是:

1.递归进入左子树,构造左链:left_tree = 2->3->4

2.递归进入右子树,构造右链:right_tree = 5->6

3.最后拼成:1->2->3->4->5->6

由于 左链 + 右链 这一步需要让 左链 的尾节点(或者说叶子节点)连到右链的根节点, 所以递归函数需要返回的是链的叶子节点(或者说尾节点) tail

动画模拟

这里用两个样例来模拟一遍算法,帮助大家更好理解代码逻辑,请逐帧观看+分析👇

Your browser doesn't support video tag.

代码实现

from typing import Optional


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:
        def flatten_tail(node: Optional[TreeNode]) -> Optional[TreeNode]:
            # 空树没有尾节点,直接返回 None
            if node is None:
                return None
            # 先保存当前节点原本的左子树和右子树的根节点
            left_head = node.left
            right_head = node.right
            # 递归展开左右子树成链
            left_tail = flatten_tail(node.left)
            right_tail = flatten_tail(node.right)

            # root -> 左链表 -> 右链表
            # 如果左链不为空,则拼接左链和右链
            if left_head:
                # 根 + 左链
                node.right = left_head
                # 题目要求拉平后的树不能有左指针
                node.left = None
                # 左链 + 右链
                left_tail.right = right_head

            # 返回尾节点
            # 如果原来有右子树,那么最终尾节点一定是右链表的尾节点
            # 如果没有右子树但有左子树,那么最终尾节点是左链表的尾节点
            # 如果左右子树都没有,那么当前 node 自己就是尾节点
            return right_tail or left_tail or node

        flatten_tail(root)



def build_tree(tree_arr):
    if not tree_arr or tree_arr[0] is None:
        return None

    q = []
    rt = TreeNode(tree_arr[0])
    q.append(rt)
    index = 1
    while q and index < len(tree_arr):
        node = q.pop(0)
        if index < len(tree_arr) and tree_arr[index] is not None:
            node.left = TreeNode(tree_arr[index])
            q.append(node.left)
        index += 1
        if index < len(tree_arr) and tree_arr[index] is not None:
            node.right = TreeNode(tree_arr[index])
            q.append(node.right)
        index += 1
    return rt


def serialize_flattened(root: Optional[TreeNode]) -> str:
    # 按题目输出风格:val null val null ...
    out = []
    cur = root
    while cur is not None:
        out.append(str(cur.val))
        if cur.right is not None:
            out.append("null")
        cur = cur.right
    return " ".join(out)


def main():
    # ACM 输入:一行层序,null 表示空节点
    # 例如:1 2 5 3 4 null 6
    tokens = input().split()
    tree_arr = []
    for x in tokens:
        if x == "null":
            tree_arr.append(None)
        else:
            tree_arr.append(int(x))

    rt = build_tree(tree_arr)
    Solution().flatten(rt)
    print(serialize_flattened(rt))


if __name__ == "__main__":
    main()

面试问答

1. 本题的核心思路是什么?

从根节点开始递归,每次先递归展开左右子树成链,再按 node -> left -> right 拼起来。为了能够正常拼接,需要让递归返回尾节点 tail

每个节点只处理一次,时间复杂度 O(n)。空间主要是递归栈,最坏 O(n)(链状树),平衡树约 O(log n)。

登录后即可使用 AI 分析。

模式
倒计时时长
:

最长 10 小时 59 分;应用后按此时长重新开始。

提示:点击提交记录在左侧题面区域查看详情
题库
AI分析设置
留空使用官方API Key,每天有次数限制(自定义API Key仅限会员和管理员使用,不限次数)
会员和管理员可切换模型;切到 Kimi/智谱/通义/豆包时需填写对应供应商 API Key
升级会员,可将运行与提交冷却时间缩短至 1 秒起

Status

  • Judging Queue
  • Service Status

Development

  • Open Source

Support

  • Help
  • Contact Us

About

  • About
  • Privacy
  • Terms of Service
  • Copyright Complaint
  1. Language
    1. English
    2. 한국어
    3. 简体中文
    4. 正體中文
  2. Legacy mode
  3. Theme
    1. Light
    2. Dark
  1. 京ICP备2025123107号-1
  2. Worker 2, 34ms
  3. Powered by Hydro v5.0.0-beta.18 Community
CLOSE


ScanQRCodePrompt

请使用微信扫描下方二维码完成注册

Forgot password or username?