【LeetCode】426. 将二叉搜索树转化为排序的双向链表(剑指 Offer 36)

2023-10-29

一、题目

将一个 二叉搜索树 就地转化为一个 已排序的双向循环链表 。

对于双向循环列表,你可以将左右孩子指针作为双向循环链表的前驱和后继指针,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

特别地,我们希望可以 就地 完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中最小元素的指针。

示例 1:

输入:root = [4,2,5,1,3] 
输出:[1,2,3,4,5]
解释:下图显示了转化后的二叉搜索树,实线表示后继关系,虚线表示前驱关系。

示例 2:

输入:root = [2,1,3]
输出:[1,2,3]

示例 3:

输入:root = []
输出:[]
解释:输入是空树,所以输出也是空链表。

示例 4:

输入:root = [1]
输出:[1]

提示:

  • -1000 <= Node.val <= 1000
  • Node.left.val < Node.val < Node.right.val
  • Node.val 的所有值都是独一无二的
  • 0 <= Number of Nodes <= 2000

二、解决

1、递归

思路:

题目要求转换为 排序,双向循环链表
1、排序:二叉搜索树的中序遍历有序,从小到大排序。
2、双向:构建相邻节点,前驱为pre,当前为cur,pre.right = cur; cur.left = pre;
3、循环:头节点head、尾节点tail,构建head.left = tail; tail.right = head;

1
这用了中序遍历,附下递归模板:

// V1
public List<Integer> inorderTraversal(TreeNode root) {
	List<Integer> result = new LinkedList<Integer>();
	if(root==null) return result;
	result.addAll(inorderTraversal(root.left));  // pre.addAll()
	result.add(root.val);
	result.addAll(inorderTraversal(root.right));
	return result;
}

// V2
public List<Integer> inorderTraversal(TreeNode root) {
	List<Integer> result = new LinkedList<Integer>();
	preHelper(root, result);
	return result;
}
public void preHelper(TreeNode root, List<Integer> result) {
	if(root==null) return;
	preHelper(root.left, result);
	result.add(root.val);	
	preHelper(root.right, result);
}

代码:

class Solution {
    Node pre, head;
    public Node treeToDoublyList(Node root) {
        if(root == null) return null;
        dfs(root);
        head.left = pre;
        pre.right = head;
        return head;
    }
    private void dfs(Node cur) {
    	// 1-Terminator
        if(cur == null) return;

        // 4-Drill down:递归遍历左子树
        dfs(cur.left);

		// 2-Current logic:若节点pre不空,pre只赋值一次
        if(pre != null) pre.right = cur;
        // 若节点pre空,pre只赋值一次
        else head = cur;
        // 上一步连接两个节点 pre-->cur, 本步 pre<--cur
        cur.left = pre;
        // 移动:pre移到下一个节点
        pre = cur;

		// 4-Drill down
        dfs(cur.right);
    }
}

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)

2、迭代

思路:

这其实算二叉树中序遍历(迭代版)的变形。

附两个二叉树中序遍历的迭代版本:

public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Deque<TreeNode> stack = new ArrayDeque<>();
    TreeNode p = root;
    while(!stack.isEmpty() || p != null) {
        if(p != null) {
            stack.push(p);
            p = p.left;
        } else {
            TreeNode node = stack.pop();
            result.add(node.val);  // Add after all left children
            p = node.right;   
        }
    }
    return result;
}

代码:

class Solution {
    Node head, pre;
    public Node treeToDoublyList(Node root) {
        if (root == null) return null;
        Deque<Node> stack = new ArrayDeque<>();
        Node p = root;
        while(!stack.isEmpty() || p != null) {
            if(p != null) {
                stack.push(p);
                p = p.left;
            } else {
                Node node = stack.pop();
                if (pre == null) {
                    head = node;
                } else {  // 否则将当前节点与pre连接,同时移动pre
                    pre.right = node;
                }
                node.left = pre;
                pre = node;
                p = node.right;   
            }
        }
        head.left = pre;
        pre.right = head;
        return head;
    }
}

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)

三、参考

1、面试题36. 二叉搜索树与双向链表(中序遍历,清晰图解)
2、JAVA 迭代 递归两种方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【LeetCode】426. 将二叉搜索树转化为排序的双向链表(剑指 Offer 36) 的相关文章

  • 从零实现一个在线考试系统

    晚上好 我是老北 公众号 GitHub 指北 会推荐 GitHub 上有用有趣的项目 挖掘开源的价值 欢迎关注 基于 SpringBoot Mybatis Plus Shiro mysql redis 构建的智慧云智能教育平台 架构上使用完

随机推荐

  • 前端交互设计利器--MVVM框架avalon.js

    前端交互设计 少不了使用js框架 特别是近来非常火爆的MVVM框架 MVVM框架的确是前端交互设计的利器 最近接触到国内大牛编写的前端框架 avalon js 功能强大 兼容性好 非常好用 MVVM框架核心思想是模型数据与视图绑定 改变了模
  • AI聊天机器人,你更爱哪个?

    嗨 各位同学 最近这几个人工智能助手可是火得很啊 叮咚 AI哥们儿ChatGPT已经很强了 轻松应对各种问题 文笔挺不错的 咻 Anthropic公司的Claude也很给力 聊天能力十分强大 嗖 Google新出的Bard看着也很厉害 刚一
  • 中国自主可控计算机大会、,2019CCF自主可控计算机大会召开

    nbsp nbsp nbsp nbsp光明网讯 齐柳明 7月23日至24日 2019CCF自主可控计算机大会 在北京召开 会议以 应用驱动 协同创新 自主可控发展的源泉和动力 为主题 大会在目前自主可控计算机发展态势良好基础上 针对相关信息
  • css 选择除了某个类下的所有某种元素

    要求 选择除了某个类下的所有input输入框 非页脚下的输入框高度 input not bs table foot input height 40px important line height 40px important
  • PyTorch框架中使用早停止Early Stopping(含详细代码)

    文章目录 1 什么是早停止 为什么使用早停止 2 如何使用早停止 3 Refferences 1 什么是早停止 为什么使用早停止 早停止 Early Stopping 是 当达到某种或某些条件时 认为模型已经收敛 结束模型训练 保存现有模型
  • vue.config.js基本配置

    方法一 vue3 vue config js const defineConfig require vue cli service module exports defineConfig transpileDependencies true
  • visual studio下C4146错误分析与整理

    C4146报错原因分析 标签 空格分隔 C C4146 一元负运算符应用于无符号类型 结果仍为无符号型 文章目录 C4146报错原因分析 toc 事发现场 翻车过程 翻车原因 解决方案 番外篇 事发现场 include
  • 如何看待越来越多年轻人追捧「摸鱼哲学」,拒绝努力的年轻人真比老一辈活得更通透吗?

    题目是我在知乎上看到的 有些小伙伴应该也看到了 不知道有没有触动到你 反正我是心有戚戚焉 上周五 我去了一趟郑州 见了几个大学同学 吃了一顿饭 喝了点小酒之后 我们谈了很多各自的现状 龙仔和小龙都说 公司现在的年轻人 真不知道在想些什么 任
  • Linux主流架构运维工作简单剖析

    随着IT运维的不断发展 尤其的Linux的飞速发展 越来越多的企业开始使用Linux操作系统平台 例如CentOS RedHat Ubuntu Fedora等等 成千上亿个网站涌现在当今互联网 互联网已经成为必不可少的工具 那今天我们跟大家
  • 数据库原理 知识点总结

    名词积累 数据库 Database 存放和提供数据的 库房 数据 Data 数据库中存储的基本对象 数据库管理系统 DBMS 位于用户与操作系统之间的一层数据管理软件 数据库系统 Database System 包括数据库 DBMS 应用系
  • Git提交代码或文件

    一 直接通过git命令提交 1 git add 将所有文件加到提交区 2 git commit m 注释 提交注释 3 git pull rebase origin master 拉去代码 且把提交的线路融合在一起 4 git push u
  • Java中转化Stream流及多个Stream流如何合并

    题目 如何将对象转化为Stream流及多个Stream流如何合并 特别注意基本类型数组转化成的流 准备 Java中Stream流是JDK1 8出现的新特性 Stream流多用于过滤 转换 统计等 Stream类的静态方法 Stream co
  • javaScript-----数组使用字符串作为下标

    原文地址 http blog csdn net chenssy article details 7366160 首先Array是从Object那里继承下 它具备Object所有的功能和特性 下面是Object的情况 html view pl
  • 完美的Apache静态.htaccess文件 [discuz和home带301重定向]

    完美的Apache静态 htaccess文件 discuz和home带301重定向 本帖最后由 下砂 于 2009 11 13 10 32 编辑 先后修改过三次 加了301重定向 顶级域名和论坛二级域名 后rewrite base保持 状态
  • 无法加载训练好的.h5权重

    Unable to open file unable to open file name h5 errno 2 error message No such file or directory 确认模型是正确的情况下 最好的办法是升级h5py
  • AD中如何做出爱心❤的丝印

    不知道有没有小伙伴试过在AD中做一个爱心的丝印 今天在这里就跟大家分享一下 如何做一个带爱心 的丝印 具体方法就是我们在字符串输入框中输入相应的内容和 爱心 的话可以通过搜狗输入法打一个 心 字就会弹出哦 选择字体 MS UI Gothic
  • 《逻辑与计算机设计基础(原书第5版)》——2.9 硬件描述语言—VHDL

    2 9 硬件描述语言 VHDL 由于硬件描述语言用来描述和设计硬件 故在使用该语言编程时 应牢记底层的硬件实现 特别是当你的设计将用来综合时 例如 如果忽略将要生成的硬件 那么你可能会用低效的硬件描述语言设计出一个大且复杂的门级结构 而实际
  • Harmony Codelab 样例—弹窗基本使用

    一 介绍 本篇 Codelab 主要基于 dialog 和 button 组件 实现弹窗的几种自定义效果 具体效果有 1 警告弹窗 点击确认按钮弹窗关闭 2 确认弹窗 点击取消按钮或确认按钮 触发对应操作 3 加载弹窗 展示加载中效果 4
  • 我与西门子的面试全过程(一面+二面)_2008校园招聘_笔试与面试分享_UNUS.CN

    导读 很庆幸自己能够参加世界500强企业 西门子的面试 经过了一面和二面 虽然最后没有被录取 但高兴的是我们广工有两个进了 在这里祝福他们 今天终于有空 写下自己与西门子的全过程 写下这篇文章 并不是想炫耀 而是真心希望对后来者有帮助 在学
  • 【LeetCode】426. 将二叉搜索树转化为排序的双向链表(剑指 Offer 36)

    一 题目 将一个 二叉搜索树 就地转化为一个 已排序的双向循环链表 对于双向循环列表 你可以将左右孩子指针作为双向循环链表的前驱和后继指针 第一个节点的前驱是最后一个节点 最后一个节点的后继是第一个节点 特别地 我们希望可以 就地 完成转换