leetcode 114. 二叉树展开为链表

75 阅读2分钟

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

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

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。 展开后的单链表应该与二叉树 先序遍历 顺序相同。  

示例 1:

输入:root = [1,2,5,3,4,null,6] 输出:[1,null,2,null,3,null,4,null,5,null,6]

思路分析:

本题需要我们将二叉树转换成一个单链表,并将所有左指针指向null,右指针指向下一个节点,并且展开的单链表需要与二叉树的先序遍历顺序相同,那么我们是否可以先将二叉树按照先序遍历的方式进行收集每一个节点,然后将收集完的每一个节点循环改变其左右子节点,以达到目标。

那么接下来的关键就在于二叉树的先序遍历如何实现呢,二叉树的先序遍历是根左右的顺序,首先是根节点,然后在输出左节点,最后在输出右节点,通过使用递归的方式,我们可以实现二叉树的先序遍历

function deep (root,list){
    if(!root)return
    list.push(root)
    deep(root.left,list)
    deep(root.right,list)
}

然后,我们可以将数组里面的的每一个元素进行遍历,并将左节点设置为null,右子节点设置为数组的下一个元素

完整代码如下

var flatten = function(root) {
    if(!root)return
    let list = []
    deep(root,list)
    let sz = list.length
    for(let i = 1;i<sz;i++){
        list[i-1].left = null
        list[i-1].right = list[i]
    }
    return list[0]
};

function deep (root,list){
    if(!root)return
    list.push(root)
    deep(root.left,list)
    deep(root.right,list)
}

这种实现方式呢需要我们先递归收集二叉树的节点,再对二叉树的节点进行处理,那是否有办法可以一边收集二叉树的节点一边处理节点呢,我们可以使用迭代的方式来收集二叉树的节点,然后在过程中进行处理

var flatten = function(root) {
    if (root === null) {
        return;
    }
    const stack = [];
    stack.push(root);
    let prev = null;
    while (stack.length) {
        const curr = stack.pop();
        if (prev !== null) {
            prev.left = null;
            prev.right = curr;
        }
        const left = curr.left, right = curr.right;
        if (right !== null) {
            stack.push(right);
        }
        if (left !== null) {
            stack.push(left);
        }
        prev = curr;
    }
};