热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

剑指Offer(7)[BinaryTree]二叉搜索树转换双向链表

点击查看剑指Offer全解【Java&Golang】实现题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,

点击查看剑指Offer全解【Java & Golang】实现


题目描述

在这里插入图片描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。




思路

第一种思路比较直观,使用一个容器收集中序遍历结果,并且将其连接成双向链表即可,这种做法会使用额外的空间复杂度。

第二种思路是通过栈实现中序遍历,在每次中序遍历过程中获取当前节点,并让当前节点和上一个节点相连,并将当前节点设置为上一个节点。这样的做法只需要中序遍历一次即可获取到双线链表,并且不需要使用容器存储整个链表,节约空间。




Java第一种解法【额外的空间复杂度】

/**
public class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;}
}
*/

import java.util.*;
public class Solution {public TreeNode Convert(TreeNode root) {if (root &#61;&#61; null) {return null;}// 中序遍历获取到排序的树节点数组ArrayList<TreeNode> list &#61; new ArrayList<>();inorder(root, list);// 将中间部分节点依次首位连接for (int i &#61; 1; i < list.size() - 1; i&#43;&#43;) {TreeNode node &#61; list.get(i);node.left &#61; list.get(i - 1);node.right &#61; list.get(i &#43; 1);}// 处理头节点list.get(0).left &#61; null;list.get(0).right &#61; (list.size() > 1) ? list.get(1) : null;// 处理尾节点list.get(list.size() - 1).left &#61; (list.size() > 1) ? list.get(list.size() - 2) : null;list.get(list.size() - 1).right &#61; null;return list.get(0);}private void inorder(TreeNode root, ArrayList<TreeNode> list) {if (root &#61;&#61; null) {return;}inorder(root.left, list);list.add(root);inorder(root.right, list);}
}

Java第二种解法【使用栈做中序遍历】

/**
public class TreeNode {int val &#61; 0;TreeNode left &#61; null;TreeNode right &#61; null;public TreeNode(int val) {this.val &#61; val;}}
*/

import java.util.*;
public class Solution {public TreeNode Convert(TreeNode root) {if (root &#61;&#61; null) {return null;}// 中序遍历获取到排序的树节点数组TreeNode res &#61; null;TreeNode pre &#61; null;boolean first &#61; true;Stack<TreeNode> stack &#61; new Stack<>();while (!stack.isEmpty() || root !&#61; null) {if (root !&#61; null) {stack.push(root);root &#61; root.left;} else {TreeNode pop &#61; stack.pop();if (first) {// 是第一个节点res &#61; pop;pre &#61; pop;pop.left &#61; null;first &#61; false;} else {// 是中间节点或尾节点&#xff0c;前后相连pre.right &#61; pop;pop.left &#61; pre;// 将当前节点置为前一个节点pre &#61; pop;}root &#61; pop.right;}}return res;}
}

推荐阅读
  • 本文详细介绍了HashSet类,它是Set接口的一个实现,底层使用哈希表(实际上是HashMap实例)。HashSet不保证元素的迭代顺序,并且是非线程安全的。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ... [详细]
  • 深入理解Java多线程与并发机制
    本文探讨了Java多线程和并发机制的核心概念,包括多线程类的分类、执行器框架、并发容器及控制工具。通过详细解析这些组件,帮助开发者更好地理解和应用多线程技术。 ... [详细]
  • LeetCode 实战:寻找三数之和为零的组合
    给定一个包含 n 个整数的数组,判断该数组中是否存在三个元素 a、b、c,使得 a + b + c = 0。找出所有满足条件且不重复的三元组。 ... [详细]
  • 贡献转移在计算每个元素的作用的时候,我们可以通过反向枚举作用效果,添加到作用元素的身上,这种方法叫做贡献转移。更正式的说, ... [详细]
  • 深入解析 C++ 中的 String 和 Vector
    本文详细介绍了 C++ 编程语言中 String 和 Vector 的使用方法及特性,旨在帮助开发者更好地理解和应用这两个重要的容器。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • 本文详细介绍了 Redis 中的主要数据类型,包括 String、Hash、List、Set、ZSet、Geo 和 HyperLogLog,并提供了每种类型的基本操作命令和应用场景。 ... [详细]
  • 本文详细探讨了在Java中如何将图像对象转换为文件和字节数组(Byte[])的技术。虽然网络上存在大量相关资料,但实际操作时仍需注意细节。本文通过使用JMSL 4.0库中的图表对象作为示例,提供了一种实用的方法。 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • 本文档详细介绍了软通动力Java开发工程师职位的笔试题目,涵盖了Java基础、集合框架、JDBC、JSP等内容,并提供了详细的答案解析。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • Spring 中策略模式的应用:Resource 接口详解
    本文探讨了在 Spring 框架中如何利用 Resource 接口实现资源访问策略。Resource 接口作为资源访问策略的抽象,通过多种实现类支持不同类型的资源访问。 ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
author-avatar
耶丝儿小丶姐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有