114. 二叉树展开为链表

371 阅读1分钟

题目介绍

力扣114题:leetcode-cn.com/problems/fl…

image.png

分析

函数签名如下:

void flatten(TreeNode root);

我们尝试给出这个函数的定义:

flatten函数输入一个节点root,那么以root为根的二叉树就会被拉平为一条链表

我们再梳理一下,如何按题目要求把一棵树拉平成一条链表?很简单,以下流程:

1、将root的左子树和右子树拉平。

2、将root的右子树接到左子树下方,然后将整个左子树作为右子树。

image.png

上面三步看起来最难的应该是第一步对吧,如何把root的左右子树拉平?其实很简单,按照flatten函数的定义,对root的左右子树递归调用flatten函数即可:

// 定义:将以 root 为根的树拉平为链表
void flatten(TreeNode root) {
    // base case
    if (root == nullreturn;

    flatten(root.left);
    flatten(root.right);

    /**** 后序遍历位置 ****/
    // 1、左右子树已经被拉平成一条链表
    TreeNode left = root.left;
    TreeNode right = root.right;

    // 2、将左子树作为右子树
    root.left = null;
    root.right = left;

    // 3、将原先的右子树接到当前右子树的末端
    TreeNode p = root;
    while (p.right != null) {
        p = p.right;
    }
    p.right = right;
}

你看,这就是递归的魅力,你说flatten函数是怎么把左右子树拉平的?不容易说清楚,但是只要知道flatten的定义如此,相信这个定义,让root做它该做的事情,然后flatten函数就会按照定义工作。

另外注意递归框架是后序遍历,因为我们要先拉平左右子树才能进行后续操作。