024.两两交换链表中的节点,用递归和 while 循环

题意

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

难度

中等

示例

输入:head = [1,2,3,4]
输出:[2,1,4,3]

分析 1

看到这道题,我们要先搞清楚什么是两两交换,比如 1->2->3->4,交换后就是 2->1->4->3。

第一个和第二个交换,第三个和第四个交换,以此类推。

我们可以用递归来解决这个问题,递归的终止条件是当前节点或者下一个节点为空,那么递归的返回值就是当前节点。

比如说 1 和 2 交换后, 2 的 next 指向 1,1 的 next 指向下一次交换后的结果。

我们来看题解的代码:

class Solution {public ListNode swapPairs(ListNode head) {// 递归终止条件:链表没有节点或只有一个节点if (head == null || head.next == null) {return head;}// 准备交换ListNode firstNode = head;ListNode secondNode = head.next;// 递归处理剩下的节点firstNode.next = swapPairs(secondNode.next);// 交换secondNode.next = firstNode;// 返回交换后新的头节点return secondNode;}
}

本地测试


/*** @ClAssName SwapPairs* @Description 两两交换链表中的节点,用递归和 while 循环轻松解决* @Author 欧妮甲是神仙* @Date 2024/6/24 19:{MINUTE}*/
public class SwapPairs {public static void main(String[] args) {SwapPairs swapPairs = new SwapPairs();ListNode head = swapPairs.new ListNode(1);head.next  = swapPairs.new ListNode(2);head.next.next  = swapPairs.new ListNode(3);head.next.next.next  = swapPairs.new ListNode(4);ListNode result = swapPairs.swapPairs(head);while (result !=null){System.out.println(result.val + " ");result = result.next;}}class ListNode{int val;  //数据ListNode next;  //指针ListNode(){};  //空参构造ListNode(int val){  //数据对象this.val = val;}//完整的对象ListNode(int val , ListNode next){this.val=val;this.next = next;}}public  ListNode swapPairs(ListNode head){//1、递归终止条件:链表没有节点或只有一个节点if (head == null || head.next ==null){return head;}//2、准备交换//第一个节点ListNode firstNode = head;//第二个节点ListNode secondeNode = firstNode.next;//3、递归·处理后续节点  重点  =后面的处理后续节点的,比如3和4的   =前面是连接后续的节点的firstNode.next = swapPairs(secondeNode.next);//4、交换secondeNode.next = firstNode;//5、返回交换完后新的头节点return secondeNode;}}

我们从链表的头节点 head 开始递归,每次处理一对节点,交换这对节点后,递归处理剩下的节点。

如果链表没有节点或者只有一个节点,没有交换的需要,直接返回 head。看下面这幅图就明白了。

来看题解效率:

分析 2

如果不想使用递归的话,我们也可以使用一个 while 循环来解决。

第一步,我们创建一个虚拟节点作为新链表的头节点,这可以简化边界条件的处理,虚拟节点的下一个节点指向 head。

第二步,我们开始 while 循环,条件是 head 和 head.next 都不为空。

第三步,我们使用两个临时变量来保存 head 和 head.next,然后交换这两个节点。

第四步,记得更新指针。

第五步,返回虚拟节点的下一个节点。

我们来看下面的代码:

class Solution {public ListNode swapPairs(ListNode head) {// 创建哑节点ListNode dummy = new ListNode(-1);dummy.next = head;ListNode prev = dummy;while (prev.next != null && prev.next.next != null) {ListNode curr = prev.next; // 当前节点ListNode next = curr.next; // 下一个节点// 交换 curr 和 nextcurr.next = next.next;next.next = curr;prev.next = next;// 移动指针prev = curr;}return dummy.next;}
}

简单解释下:

  • 创建一个虚拟节点 dummy,dummy 的 next 指向 head。
  • 创建一个指针 prev,指向 dummy。
  • 当 prev 的 next 和 next 的 next 都不为空时,进行交换。
  • 交换后,prev 指向 curr,curr 指向 next,next 指向 curr 的 next。
  • 返回 dummy 的 next。

因为增加了很多临时变量,所以代码没有递归简洁。

    public  ListNode swapPairsTwo(ListNode head){//1、创建一个虚拟的节点作为新链表的头节点,简化边界条件的处理,其下一个节点指向headListNode dummy = new ListNode(-1);dummy.next = head;ListNode prev = dummy;//2、我们while循环 ,条件是head和head.next都不为空while (prev.next != null &&prev.next.next != null){//3、使用两个临时变量来保存head和head.next,然后交换这两个节点ListNode curr = prev.next;  //当前节点ListNode next = prev.next.next;  // 下一个节点//4、交换curr和nextcurr.next = next.next;next.next = curr;prev.next = next;//5、移动指针prev = curr;}//最后返回头节点return dummy.next;}

来看题解效率:

总结

其实有关链表的相关题目,最重要的切入角度,就是理清楚节点之间的关系,然后在纸上画一画,不要一个劲的只靠脑子不靠笔,往往思考了很久的问题,动动笔,就会豁然开朗,再用代码准确的描述出思路,这样子链表的问题便迎刃而解。

那这道题考察的还是链表的数据结构,以及递归和 while 循环的一些临时变量和边界条件。

力扣链接:. - 力扣(LeetCode)

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

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

相关文章

什么是车载测试?车载测试怎么学!

1、车载测试是什么? 车载测试分很多种,有软件测试、硬件测试、性能测试、功能测试等等,每一项测试的内容都不一样,我们所说的车载测试主要指的是汽车软件的功能测试,也就是针对汽车实现的某一个功能,而进行…

vue3 vxe-grid列中绑定vxe-switch实现数据更新

1、先上一张图&#xff1a; <template #valueSlot"{ row }"><vxe-switch :value"getV(row.svalue)" change"changeSwitch(row)" /></template>function getV(value){return value 1;};function changeSwitch(row) {console.l…

Trilium windows上修改笔记目录,创建多个笔记空间方法

一开始使用trilium会非常的不舒服&#xff0c;不像是obsidian可以创建多个笔记空间&#xff0c;指定多个笔记目录。这里摸索到了解决方案 修改目录的方法一 ——修改系统环境变量 打开控制面板-系统-高级系统设置 新增如上条目 修改目录的方法二——直接写bat脚本运行 新建位…

网安大咖说·镜鉴(下)| 把握安全新脉搏:企业CSO的领航之道

网安大咖说镜鉴栏目通过对网安大咖说嘉宾访谈内容的深度提炼&#xff0c;撷取群英论道之精髓&#xff0c;汇聚众智谋策之高远&#xff0c;为从业者提供宝贵的经验和启迪。集思广益、博采众长&#xff0c;意在以镜为鉴&#xff0c;观网安之百态&#xff0c;立防范之策略&#xf…

AI助力科研:自动化科学构思生成系统初探

科学研究作为推动创新和知识进步的关键活动&#xff0c;在解决复杂问题和提升人类生活水平方面发挥着至关重要的作用。然而&#xff0c;科学研究的固有复杂性、缓慢的进展速度以及对专业专家的需求&#xff0c;限制了其生产力的提升。为了增强科研效率&#xff0c;本文提出了一…

重学java 84.Java枚举

那些你暗自努力的时光&#xff0c;终究会照亮你前行的路 —— 24.6.24 一、枚举介绍&#xff08;开发中表示状态&#xff09; 1.概述&#xff1a; 五大引用数据类型&#xff1a;类型、数组、接口、注解、枚举 2.定义&#xff1a; public enum 枚举类名{} 所有的枚举类父类…

贝锐花生壳内网穿透

贝锐花生壳内网穿透使用步骤 首先你得去官网购买一个域名配置一下内网穿透映射官网下载一个客户端修改代码配置 首先你得去官网购买一个域名 配置一下内网穿透映射 官网下载一个客户端 注意&#xff0c;一定要下载客户端&#xff0c;不然用不了 当然&#xff0c;本地我已经提前…

SpringBoot-配置文件中使用随机值和使用变量

1、配置文件中使用随机值 2.在配置文件使用引用变量 如果没定义还可以设置默认值

环境安装-GIT

下载 git官网下载 https://git-scm.com/ 安装 点击下载的安装包&#xff0c;并点击下一步 选择安装路径&#xff0c;照例改选自定义路径 选择默认的即可 选择GIT编辑器&#xff0c;默认选择vim即可 设置初始化新项目(本地仓库)的主分支名&#xff0c;按默认即可&#xff0c;点…

keysight 34901A (安捷伦)多路复用器

34970A 数据采集/开关单元的 Keysight 34901A&#xff08;安捷伦&#xff09;模块是通用扫描中最通用的多路复用器。它将密集的多功能开关与 60 通道/秒的扫描速率相结合&#xff0c;可满足广泛的数据采集应用。两线和四线通道可以混合在同一模块上。两个额外的保险丝输入&…

音频傅里叶变换(基于开源kissffs)

主要参考资料&#xff1a; 深入浅出的讲解傅里叶变换&#xff08;真正的通俗易懂&#xff09;: https://zhuanlan.zhihu.com/p/19763358 推荐开源项目&#xff1a;KISS FFT&#xff1a; https://blog.csdn.net/gitblog_00031/article/details/138840117 数字硅麦数据的处理&…

基于Java蛋糕甜品商城系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…

LLama 3的各种微调:拿我司七月的paper-review数据集微调LLama 3

前言 llama 3出来后&#xff0c;为了通过paper-review的数据集微调3&#xff0c;有以下各种方式 不用任何框架 工具 技术&#xff0c;直接微调原生的llama 3&#xff0c;毕竟也有8k长度了 效果不期望有多高&#xff0c;纯作为baseline通过PI&#xff0c;把llama 3的8K长度扩展…

EDU学校漏洞sql注入挖掘记录

某搜索框 biaoti参数单引号报错 双引号正常 经过我的不断测试&#xff0c;’||exp(710)||’报错&#xff0c;exp函数就是执行e的多少次方&#xff0c;709不会报错&#xff0c;710会导致这个数太大报错 709正常,这里说明一下&#xff0c;因为这个数是小数所以返回200&#xff0c…

Spring容器启动流程——refresh()单个方法分析

文章目录 Spring启动过程this()方法refresh()prepareRefresh()obtainFreshBeanFactory()prepareBeanFactory()postProcessBeanFactory()invokeBeanFactoryPostProcessorsregisterBeanPostProcessorsinitMessageSource()initApplicationEventMulticaster()onRefresh()registerLi…

WPF 数据分组显示

WPF 数据分组显示 效果展示&#xff1a; Student类&#xff1a; public class Student {public string Name { get; set; }public string Class { get; set; }public int Age { get; set; } }MainWindow.xaml.cs public partial class MainWindow : Window {private Observ…

【调试笔记-20240620-Windows- Tauri + Vue 中实现部分区域滚动】

调试笔记-系列文章目录 调试笔记-20240620-Windows- Tauri Vue 中实现部分区域滚动 文章目录 调试笔记-系列文章目录调试笔记-20240620-Windows- Tauri Vue 中实现部分区域滚动 前言一、调试环境操作系统&#xff1a;Windows 10 专业版调试环境调试目标 二、调试步骤搜索相似…

专业140+总分400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书

专业855信号与系统140&#xff0c;总分400&#xff0c;今年顺利上岸武汉理工大学&#xff0c;总结一下自己的复习经历&#xff0c;希望对报考武理工的同学有所帮助。专业课&#xff1a;855信号与系统 首先教材&#xff1a; 《信号与系统》高等教育出版社 作者&#xff1a;刘泉…

第一百二十三节 Java面向对象的设计 - Java接口继承

Java面向对象的设计 - Java接口继承 接口可以从另一个接口继承。与类不同&#xff0c;接口可以从多个接口继承。 interface Singer {void sing();void setRate(double rate);double getRate(); } interface Writer {void write();void setRate(double rate);double getRate();…

人间烟火气视频素材去哪里找?人间生活气息视频素材网站分享

在数字化时代迅猛发展的今天&#xff0c;短视频已经成为人们表达情感、记录生活的流行方式。无论是在抖音、快手还是B站&#xff0c;一种特别的元素——人间烟火气&#xff0c;为短视频增添了无尽魅力。许多创作者常常困惑&#xff0c;这种生活气息浓厚的视频素材应当如何寻找&…