多种方法解决leetcode经典题目-LCR 155. 将二叉搜索树转化为排序的双向链表, 同时弄透引用变更带来的bug
1 描述
2 解法一: 使用list列表粗出中序遍历的结果,然后再依次处理list中的元素并且双向链接
public Node treeToDoublyList2(Node root) {if(root==null)return root;Node dummy=new Node(-10000);List<Node>ans=new ArrayList<>();dfs2(root,ans);Node pre=ans.get(0);dummy.right=pre;for(int i=1;i<ans.size();i++){Node cur=ans.get(i);pre.right=cur;cur.left=pre;pre=cur;}dummy.right.left=pre;pre.right=dummy.right;return dummy.right;}void dfs2(Node root, List<Node>ans){if(root==null){return;}dfs2(root.left,ans);ans.add(root);dfs2(root.right,ans);}
3 解法二:使用一个全局变量作为前驱节点,同时使用一个虚拟头节点指向这个前驱,在使用dfs的时候进行双向链接,然后通过dummy虚拟头节点完成链表循环
Node pre;public Node treeToDoublyList(Node root) {if(root==null)return root;Node dummy=new Node(-10000);pre=dummy;dfs(root);pre.right=dummy.right;dummy.right.left=pre;return dummy.right;}void dfs(Node root){if(root==null){return;}dfs(root.left);pre.right=root;root.left=pre;pre=root;dfs(root.right);}
4 解法三:通过引用传递
4.1 版本一:数组引用传递(执行无误)
public Node treeToDoublyList(Node root) {if(root==null)return root;Node dummy=new Node(-10000);Node prev[]=new Node[1];prev[0]=new Node(100001);dummy=prev[0];dfs4(root,prev);prev[0].right=dummy.right;dummy.right.left=prev[0];return dummy.right;}void dfs4(Node root,Node[] prev){if(root==null){return;}dfs4(root.left,prev);prev[0].right=root;root.left=prev[0];prev[0]=root;dfs4(root.right,prev);}
4.2 版本二:通过变量引用传递(但是执行起来有问题)
public Node treeToDoublyList(Node root) {if(root==null)return root;Node dummy=new Node(-10000);Node pre=dummy;dfs(root);pre.right=dummy.right;dummy.right.left=pre;return dummy.right;}void dfs3(Node root,Node pre){if(root==null){return;}dfs3(root.left,pre);pre.right=root;root.left=pre;pre=root;dfs3(root.right,pre);}
4.3 比较一下版本1和2,2中哪里出错了,为什么错了?
这段代码实际上是一个常见的算法题目的解法,目标是将一个二叉搜索树转换为一个排序的双向链表。整个过程是通过中序遍历来实现的,遍历过程中修改节点的左右指针来构建双向链表。代码中使用了一个额外的节点 dummy
来帮助构建双向链表,并使用 pre
节点来保存前一个遍历到的节点。
代码中的错误主要在 dfs3
方法中,pre
节点作为参数传递,但在递归调用中并没有更新 pre
的值。这会导致链表构建不正确。要修复这个问题,你需要在 dfs3
方法中更新 pre
的值。下面是修正后的 dfs3
方法:
void dfs3(Node root,Node[] pre){if(root==null){return;}dfs3(root.left,pre);pre[0].right=root;root.left=pre[0];pre[0]=root;dfs3(root.right,pre);
}
调用 dfs3
方法时,你需要传递一个 Node
类型数组作为 pre
参数,例如:
Node[] pre = new Node[1];
pre[0] = dummy;
dfs3(root, pre);
这样,pre
数组中的元素会在 dfs3
方法中被正确更新,从而可以构建正确的双向链表。
4.4 这里的Node pre是作为值传递的嘛?你改为传递长度为1的Node数组,就变成了引用传递?
在Java中,对象的引用是通过值传递的。这意味着当你将一个对象作为参数传递给一个方法时,你实际上是将对象引用的副本传递给了方法。如果你在方法内部修改引用所指向的对象的状态,这个修改会反映到方法外部。但是,如果你尝试直接修改引用本身(例如,使其指向一个新的对象),这个修改不会影响到方法外部的引用。
在你的代码中,Node pre
是一个对象引用,当你将其作为参数传递给 dfs3
方法时,你传递的是引用的副本。在 dfs3
方法内部,你可以修改 pre
引用所指向的 Node
对象的状态,但是如果你尝试直接修改 pre
引用本身(例如,pre = new Node(…)
, pre = root
),这个修改不会影响到方法外部的 pre
引用。
为了在 dfs3
方法内部更新外部的 pre
引用,你可以使用一个 Node
类型的数组,如我之前所示。数组在Java中是一个对象,当你将数组作为参数传递给一个方法时,你传递的是数组对象引用的副本。你可以在方法内部修改数组内容,这些修改会反映到方法外部。因此,你可以使用一个数组来包装 pre
引用,然后在 dfs3
方法内部更新数组的内容,这样就能够实现在方法调用后更新外部的 pre
引用。
相关文章:

多种方法解决leetcode经典题目-LCR 155. 将二叉搜索树转化为排序的双向链表, 同时弄透引用变更带来的bug
1 描述 2 解法一: 使用list列表粗出中序遍历的结果,然后再依次处理list中的元素并且双向链接 public Node treeToDoublyList2(Node root) {if(rootnull)return root;Node dummynew Node(-10000);List<Node>ansnew ArrayList<>();dfs2(root,ans);Node p…...
C/C++ 实现UDP发送或接收组播消息,并可指定接收发送网卡
一、发送端代码 #include <iostream> #include <unistd.h> #include <stdio.h> #include <string.h> #include <net/if.h> #include <netinet/in.h> #include <netdb.h> #include <sys/ioctl.h> #include "UDPOperation…...

纬创出售印度子公司给塔塔集团,结束iPhone代工业务 | 百能云芯
纬创(Wistron)董事会于10月27日通过决议,同意以1.25亿美元的价格出售其印度子公司Wistron InfoComm Manufacturing (India) Private Limited(WMMI)的100%股权给塔塔集团,交割将尽快完成。此举将意味着纬创退…...
vue手机项目如何控制手电筒打开与关闭
要控制手电筒,您可以使用Vue的Device API,例如cordova-plugin-flashlight或vue-native-flashlight插件。以下是一些基本步骤: 导入手电筒插件或库。在Vue组件中创建一个手电筒对象并初始化它。使用turnOn()和turnOff()方法控制手电筒。 以下…...

电商课堂|5分钟了解电商数据分析完整流程,建议收藏!
账户效果下降,如何能够快速找到问题并优化调整? 相信百分之90%的竞价员都会说:“做数据分析。” 没错,数据分析能够帮助我们快速锁定问题所在,确定优化方向,还可以帮助我们找到流量控制的方向。那么做电商&…...

Redis测试新手入门教程
在测试过程中,我们或多或少会接触到Redis,今天就把在小破站看到的三丰老师课程,把笔记整理了下,用来备忘,也希望能给大家带来亿点点收获。 主要分为两个部分: 一、缓存技术在后端架构中是如何应用的&#…...

Linux内核是如何创建进程?
目录 1.Linux如何创建进程 2.fork函数原理 2.1 fork函数原型 2.2 fork函数实现原理 2.3 父子进程虚拟地址空间(mm_struct)之间的关系 2.4 写时拷贝(copy-on-write)技术 2.5 父子进程如何共享文件(files_struct&…...

IDEA 使用技巧
文章目录 语言支持简化编写 有问题,可暂时跳过 个人常用快捷键插件主题插件功能插件 碰到过的问题 除了一些在Linux上用vim开发的大佬,idea算是很友好的集成开发工具了,功能全面,使用也很广泛。 记录一下我的 IDEA 使用技巧&#…...

安防监控项目---web网页通过A9控制Zigbee终端节点的风扇
文章目录 前言一、zigbee的CGI接口二、请求线程和硬件控制三、现象展示总结 前言 书接上期,我们可以看一下前面的功能设计的部分,网页端的控制还有一个,那就是通过网页来控制zigbee上的风扇节点,这部分的工作量是相当大的&#x…...
Ubuntu 22.04 在登录界面循环
问题描述 https://blog.csdn.net/weixin_44023406/article/details/134092271?spm1001.2014.3001.5502 接上一篇,磁盘满了,扩展空间之后能正常开机,进到登录界面,输密码3秒后又回到登录界面 分析解决问题 命令行能登录&#…...

【C++ 系列文章 -- 程序员考试 201805 下午场 C++ 专题 】
文章目录 1.1 C 题目六1.1.1 填空(1)详解1.1.1.1 C 纯虚函数介绍 1.1.2 填空(2)详解1.1.2.1 父类声明了带参构造函数1.1.2.2 子类中构造函数的构造原则 1.1.3 填空(3)详解1.1.4 填空(4ÿ…...

Python如何使用datetime模块进行日期和时间的操作
目录 一、引言 二、datetime模块的基本使用 三、日期的运算 四、注意事项 总结 本文将对Python的datetime模块进行深入探讨,阐述如何使用该模块进行日期和时间的各种操作。我们将介绍日期和时间的基本操作,以及格式化、时区处理等高级操作ÿ…...

flutter之bloc使用详解
flutter中一切皆为Widget,因此在我们开发中,往往业务和UI逻辑写在一起,这样不利于代码维护,因此状态管理框架久诞生了,这篇就开始讲一讲Bloc。 对于Bloc库有两个,如下图: flutter_bloc其实是对…...

记一次 .NET 某工厂无人车调度系统 线程爆高分析
一:背景 1. 讲故事 前些天有位朋友找到我,说他程序中的线程数爆高,让我帮忙看下怎么回事,这种线程数爆高的情况找问题相对比较容易,就让朋友丢一个dump给我,看看便知。 二:为什么会爆高 1. …...

高等数学啃书汇总重难点(九)多元函数微分法及其应用
下册最重要也是个人认为偏恶心的一节(主要东西是真不少....)重点在于会计算偏导、能理解全微分及隐函数求导3个核心内容,至于后面的关于几何层面的应用,建议掌握计算方法即可,学有余力再死磕推导过程等内容~ 1.平面点集…...

Vue3前端100个必要的知识点
为什么是必要的,就是这100个知识点学完后,能独立完成一个小项目。最终能得到一个解决方案。也算是前端知识的积累。如果后面有需要的地方可以回来查。100个其实比较多,我会按新手老鸟,大神来分成3个等级,话不多说&…...

CCS3列表和超链接样式
在默认状态下,超链接文本显示为蓝色、下画线效果,当鼠标指针移过超链接时显示为手形,访问过的超链接文本显示为紫色;而列表项目默认会缩进显示,并在左侧显示项目符号。在网页设计中,一般可以根据需要重新定…...
vue手机项目如何控制蓝牙连接
要控制蓝牙连接,您需要使用Vue的蓝牙插件或库,例如BLE-Peripheral或cordova-plugin-ble-central。以下是一些基本步骤: 导入蓝牙插件或库。在Vue组件中创建一个蓝牙对象并初始化它。扫描周围的蓝牙设备并连接到所需的设备。一旦连接成功&…...

遥遥领先,免费开源的django4-vue3项目
星域后台管理系统前端介绍 🌿项目简介 本项目前端基于当下流行且常用的vue3作为主要技术栈进行开发,融合了typescript和element-plus-ui,提供暗黑模式和白昼模式两种主题以及全屏切换,开发bug少,简单易学,…...

视频平台跨网级联视频压缩解决方案
一、 简介 视频监控领域对带宽有着较大的需求,这是因为视频流需要实时占用网络带宽资源。视频监控的传输带宽是组网结构的基础保障,关系到视频监控的稳定性、可靠性和可拓展性等因素。例如,720P的视频格式每路摄像头的比特率为2Mbpsÿ…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...