46.二叉树展开为链表

题目链接

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

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null

展开后的单链表应该与二叉树 先序遍历 顺序相同。

解法1 暴力解法

思路

和之前链表的思路一致,先将节点缓存到数组当中。之后再去改变其结构。

不过要注意的是遍历的顺序是先序遍历。

代码

js 复制代码
function flatten(root: TreeNode | null): void {
    if (!root) return;
    const list = [];
    const preorder = (node) => {
        if (!node) return;
        list.push(node);
        preorder(node.left);
        preorder(node.right);
    };

    preorder(root);
    for (let i = 0; i < list.length; i++) {
        list[i].left = null;
        list[i].right = list[i + 1];
    }

    // 最后一个节点也需要置空其左右子树
    const last = list[list.length - 1];
    last.left = null;
    last.right = null;
};

时空复杂度

时间复杂度:O(n)

空间复杂度:O(n)

解法2 莫里斯原地修改

思路

Morris 遍历的核心思想是左子树右移 + 接尾巴

原理:

对于每个当前节点 curr

  1. 如果 curr 有左子树:
  • 找到它左子树中最右边的节点 predecessor
  • curr.right 接到这个 predecessor.right
  • curr.left 移动到 curr.right,然后置空 curr.left
  1. curr 往右移。

代码

js 复制代码
function flatten(root: TreeNode | null): void {
    if (!root) return;
    let curr = root;

    while (curr) {
        if (curr.left) {
            // 找到左子树的最右节点
            let pre = curr.left;
            while (pre.right) {
                pre = pre.right;
            }

            // 将 curr 的右子树接到 pre.right
            pre.right = curr.right;

            // 把左子树移到右边
            curr.right = curr.left;
            curr.left = null;
        }

        // 移动到下一个节点
        curr = curr.right;
    }
};

时空复杂度

时间复杂度:O(n)

空间复杂度:原地修改 O(1)

相关推荐
专注前端30年13 小时前
Vue CLI与Webpack:区别解析与实战使用指南
前端·vue.js·webpack
余道各努力,千里自同风13 小时前
如何使用 Promise.all() 处理异步并发操作?
开发语言·前端·javascript
营赢盈英13 小时前
How to detect if <html> tag has a class in child Angular component
前端·javascript·css·html·angular.js
Achieve - 前端实验室13 小时前
深入浅出 ES Module
前端·javascript
littleplayer13 小时前
Combine 基本使用指南
前端
Lethehong13 小时前
TRAE SOLO:基于React 18+与蓝耘MaaS的多语言智能翻译平台设计与实现
前端·react.js·前端框架·蓝耘元生代·蓝耘maas
技算未来13 小时前
Electron中使用exceljs+Node模块编写
前端
Qinana13 小时前
🚀 用低代码构建AI职业规划应用
前端·程序员·产品
Ebin13 小时前
Shopify 前端实战系列 · S02:Theme 实战进阶
前端
青衫码上行13 小时前
【JavaWeb学习 | 第二篇】CSS(1) - 基础语法与核心概念
前端·css·学习