多种方法解决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 引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/158092.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023Python自动化测试5种模型(建议收藏)

1、前言 在自动化测试中&#xff0c;我们往往将自动化脚本都归纳属于哪种框架模型&#xff0c;比如关键字驱动模型等。 本篇将列举实际自动化测试中&#xff0c;Python 自动化测试的五种模型&#xff1a;线性模型、模块化驱动模型、数据驱动模型、关键字驱动模型、行为驱动模…

组件与Props:React中构建可复用UI的基石

目录 组件&#xff1a;构建现代UI的基本单位 Props&#xff1a;组件之间的数据传递 Props的灵活性&#xff1a;构建可配置的组件 组件间的通信&#xff1a;通过回调函数传递数据 总结&#xff1a; 组件&#xff1a;构建现代UI的基本单位 组件是前端开发中的关键概念之一。…

利用Vue2实现印章徽章组件

需要实现的组件效果&#xff1a; 该组件有设置颜色、大小、旋转度数和文本内容功能。 一、组件实现代码 <template><divclass"first-ring"v-bind"getBindValue":class"getStampBadgeClass":style"{ transform: rotate(${rotate}…

一文深入了解 CPU 的型号、代际架构与微架构

在 10 月 16 号的时候&#xff0c;Intel 正式发布了第 14 代的酷睿处理器。但还有很多同学看不懂这种发布会上发布的各种 CPU 参数。借着这个时机&#xff0c;给大家深入地讲讲 CPU 的型号规则、代际架构与微架构方面的知识。 CPU 在整个计算机硬件中、技术体系中都算是最最重…

【云原生基础】了解云原生,什么是云原生?

&#x1f4d1;前言 本文主要讲了云原生的基本概念和原则的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#x…

基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)

一、项目简介 本项目是一套基于springboot框架实现的宠物医院管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单…

【JAVA学习笔记】59 - JUnit框架使用、本章作业

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter15/src/com/yinhai/homework JUnit测试框架 1.基本介绍 1. JUnit是一个Java语言的单元测试框架 2.多数Java的开发环境都已经集成了JUnit作为单元测试的工具 2.如何使用 创建方法后&#x…

文件fd.

共识原理: 1.文件 内容 属性 2.文件分为打开的文件 和 没打开的文件 3.打开的文件: 谁打开? 进程! ----本质是研究进程和文件的关系! 根据冯诺依曼原理&#xff0c;文件被打开&#xff0c;必须先被加载到内存&#xff01;不然CPU怎么访问它 那么是文件内容被加载&#xff…

绿色通道 快速理赔,渤海财险用实干书写服务品牌

7月底&#xff0c;受台风“杜苏芮”影响&#xff0c;北京市连续强降雨&#xff0c;西部、西南部、南部遭遇特大暴雨&#xff0c;房山、门头沟、丰台等地陆续出现山洪暴发现象。      灾害无情人有情&#xff0c;为更好地保障人民群众生命财产安全&#xff0c;渤海财险北京分…

计算机视觉的监督学习与无监督学习

什么是监督学习&#xff1f; 监督学习是一种机器学习算法&#xff0c;它从一组已标记的 合成数据生成器中生成的训练数据中学习。这意味着数据科学家已经用正确的标签&#xff08;例如&#xff0c;“猫”或“狗”&#xff09;标记了训练集中的每个数据点&#xff0c;以便算法可…

部署ELK

一、elasticsearch #拉取镜像 docker pull elasticsearch:7.12.1 #创建ELK docker网络 docker network create elk #启动ELK docker run -d --name es --net elk -P -e "discovery.typesingle-node" elasticsearch:7.12.1 #拷贝配置文件 docker cp es:/usr/share/el…

AI大模型时代网络安全攻防对抗升级,瑞数信息变革“下一代应用与数据安全”

AI与大模型技术加速普及&#xff0c;安全领域也在以创新视角聚焦下一代应用安全WAAP变革&#xff0c;拓展新一代数据安全领域。近日瑞数信息重磅发布了瑞数全新API扫描器、API安全审计、数据安全检测与应急响应系统及分布式数据库备份系统四大新品。此次发布在延续瑞数信息Bot自…