「前端刷题」114. 二叉树展开为链表

78 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。

题目

链接:leetcode-cn.com/problems/fl…

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

**进阶:**你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

思路

利用递归的思想。假设递归函数treeToList能将节点p转换为单链表,那就再次利用treeToList将p的左子树、右子树都转换成单链表,再让p的右指针指向其左子树单链表,左子树单链表的右指针指向右子树单链表。因此,我们需要知道左子树最后一个元素,因此就引入了last变量,在递归函数treeToList需要时刻“维护”last。又因为在递归函数中会改变指针指向,因此需要使用left,right变量保留当前节点p的左右指针。

我犯的一个错误: 当我将leftLast,和rightLast当做指针传入进treeToList时,最后得到的值都为null。这是因为在js中,实参与形参存储的都是指向同一的地址,在函数内部只该变量形参的指向地址,实参的指向地址没有变化。所以这里需要通过函数的返回值来获取它们。

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {void} Do not return anything, modify root in-place instead.
 */
var flatten = function(root) {

    treeToList(root)
    
    return;

    function treeToList(p){
        if(!p){
            return;
        }

        // 值得注意的是,当我将leftLast,和rightLast当做指针传入进treeToList时,最后得到的值为null。
        // 这是因为在js中,实参与形参存储的都是指向同一的地址,在函数内部只该变量形参的指向地址,实参的指向地址没有变化。
        // 所以这里通过函数的返回值来获取它们。
        let leftLast = null, rightLast = null;
        let left = p.left, right = p.right;

        if(left==null && right==null){
            last = p;
        }

        if(left){
            leftLast = treeToList(left);

            p.right = left;
            p.left = null;
            last = leftLast;
        }

        if(right){
            rightLast = treeToList(right);
            last = rightLast;

            // 如果节点p只有右子树,没有左子树,就不用改变任何结构,它本身就满足题上要求。
            if(leftLast){
                leftLast.right = right;
                leftLast.left = null;
            }
        }

        return last;

    }
};