力扣题解24. 两两交换链表中的节点(图解递归和双指针)

24. 两两交换链表中的节点

题目描述:

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

示例 1:

img

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

示例 2:

输入:head = []
输出:[]

示例 3:

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

提示:

  • 链表中节点的数目在范围 [0, 100]
  • 0 <= Node.val <= 100

方法一:递归

    /*** 1、递归 -- 0ms(100.00%), 40.40MB(5.13%)* <p>* 时间复杂度:O(n)* <p>* 空间复杂度:O(n)*/class Solution {public ListNode swapPairs(ListNode head) {// 如果链表为空或只有一个节点,直接返回头节点,不需要进行交换if (head == null || head.next == null) {return head;}// 递归调用swapPairs函数,处理剩余的节点,传入头【节点的下一个节点的下一个节点】,返回值赋值给tmpListNode tmp = swapPairs(head.next.next);// 获取当前节点的下一个节点赋值给pListNode p = head.next;// 将下一个节点的next指针指向当前节点,完成交换p.next = head;// 将当前节点的next指针指向递归调用的结果,继续处理剩余的节点head.next = tmp;// 返回交换后的头节点return p;}}
代码解析

这个函数的作用是将链表中的每两个相邻节点进行交换,并返回新的头节点。具体步骤如下:

  1. 首先判断链表是否为空或只有一个节点,如果是,则直接返回头节点,因为不需要交换。
  2. 然后递归调用 swapPairs 函数,传入参数为当前节点的下一个节点的下一个节点(即跳过了两个节点)。这样可以处理剩余的节点。
  3. 接下来,获取当前节点的下一个节点,并将其赋值给变量 p
  4. pnext 指针指向当前节点,完成两个节点的交换。
  5. 将当前节点的 next 指针指向递归调用的结果,即交换后的剩余节点。
  6. 最后返回交换后的头节点 p

通过递归调用,该函数会逐层向下处理链表,直到到达链表末尾。在每一层递归中,都会交换相邻的两个节点,并将结果传递给下一层递归。最终,当递归到最底层时,所有相邻节点都被成功交换,然后逐层向上返回,最终得到交换后的链表。

图解

示例一:

image

示例二:

image

方法二:虚拟头节点 + 双指针

    /*** 2、虚拟头节点 + 双指针 -- 0ms(100.00%), 39.89MB(19.62%)* <p>* 时间复杂度:O(n)* <p>* 空间复杂度:O(1)*/class Solution2 {public ListNode swapPairs(ListNode head) {// 创建虚拟头节点,并将其 next 指向原始链表的头节点ListNode dummy = new ListNode(0, head);// 创建两个指针 pre 和 cur,将 pre 初始化为虚拟头节点ListNode pre = dummy;// 将 cur 初始化为原始链表的头节点而不是虚拟头节点ListNode cur = head;// 循环条件:当前节点 cur 和它的下一个节点 cur.next 均不为 null, 不为 null 才能进行交换while (cur != null && cur.next != null) {// 创建临时节点 tmp,保存下一个节点的引用ListNode tmp = cur.next;// 将当前节点 cur 的 next 指针指向下一个节点的下一个节点,跳过下一个节点cur.next = tmp.next;// 将临时节点 tmp 的 next 指针指向当前节点 cur,完成交换tmp.next = cur;// 将前一个节点 pre 的 next 指针指向交换后的新节点 tmppre.next = tmp;// 将 pre 移动到下一对相邻节点的前一个节点,即当前节点 curpre = cur;// 将 cur 移动到下一对相邻节点的当前节点,即下一个节点cur = cur.next;}// 返回虚拟头节点 dummy 的 next,即完成相邻节点的交换后的链表return dummy.next;}}
代码解析
  • 算法通过维护一个虚拟头节点,利用两个指针 precur 在链表中遍历,不断交换相邻的节点。

  • 这种方式可以避免对头节点的特殊处理

  • 循环里主要是三个步骤:报存引用、更换 next 指针指向、移动指针

图解

image

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

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

相关文章

解决python画图无法显示中文的问题

python画图遇到的问题&#xff1a; 中文不显示&#xff1a; 解决方法&#xff1a;把字体设置为支持中文的字体&#xff0c;比如黑体 黑体下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1BD7zQEBUfcIs6mC2CPYy6A?pwdv120 提取码&#xff1a;v120 pyhon…

CSS 选择器全攻略:从入门到精通(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Python的运算符与表达式

目录 运算符与表达式运算符算数运算符赋值运算符关系运算符逻辑运算符位运算符 运算符与表达式 运算符 算数运算符 赋值运算符 关系运算符 逻辑运算符 位运算符

力扣热题 100

文章目录 哈希双指针滑动窗口子串普通数组矩阵链表二叉树图论回溯二分查找栈堆贪心算法动态规划多维动态规划技巧 哈希 双指针 移动零 class Solution {public void moveZeroes(int[] nums) {int k 0;for(int i 0;i < nums.length; i){if(nums[i] ! 0) {nums[k] nums[…

揭秘关键指标稳定币供应比率(SSR):它如何影响你的投资?

作者&#xff1a;lesleyfootprint.network 数据源&#xff1a;The Stablecoin Dashboard 在加密世界里&#xff0c;稳定币扮演着重要的角色&#xff0c;为投资者提供了一个相对稳定的避风港。 稳定币旨在保持相对稳定的价值&#xff0c;这通常通过将它们与商品、法定货币挂钩…

(leetcode)替换所有的问号 -- 模拟算法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 本题链接 力扣&#xff08;LeetCode&#xff09; 输入描述 string modifyString(string s) 输入一个字符串&#xff0c;字符串中仅包含小写字母和 ‘?’ 字符。 输出描述 将问号替换为小写字母&#xff0c;且这个替…

全链路压力测试有哪些主要作用

全链路压力测试是在软件开发和维护过程中不可或缺的一环&#xff0c;尤其在复杂系统和高并发场景下显得尤为重要。下面将详细介绍全链路压力测试的主要作用。 一、全链路压力测试概述 全链路压力测试是指对软件系统的全部组件(包括前端、后端、数据库、网络、中间件等)在高负载…

机器学习激活函数

激活函数 激活函数是人工神经网络中的一个重要组成部分。它们用于向神经网络中添加非线性因素&#xff0c;使得网络能够解决复杂问题&#xff0c;如图像识别、语言处理等。激活函数的作用是决定一个神经元是否应该被激活&#xff0c;也就是说&#xff0c;它帮助决定神经元的输…

uni-app中实现音乐播放器

uni-app中实现音乐播放器 1、主要利用的是uni-app中提供的uni.createInnerAudioContext()来进行实现&#xff1b; 2、代码示例 &#xff08;1&#xff09;主页面代码展示 <template><view class"music-layout"><view class"tn-flex">…

ADOV路由和DSR路由matlab对比仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 ADOV路由&#xff08;Ad hoc On-demand Distance Vector Routing&#xff09; 4.2 DSR路由&#xff08;Dynamic Source Routing&#xff09; 5.完整程序 1.程序功能描述 ADOV路由和DSR…

迅为RK3568开发板Android11/12/Linux编译驱动到内核

在平时的驱动开发中&#xff0c;经常需要在内核中配置某种功能&#xff0c;为了方便大家开发和学习&#xff0c;本小 节讲解如何在内核中添加驱动。具体的讲解原理讲解请参考本手册的驱动教程。 Android11 源码如果想要修改内核&#xff0c;可以运行以下命令进行修改: cd ke…

【python】python新年烟花代码【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 新年的钟声即将敲响&#xff0c;为了庆祝这个喜庆的时刻&#xff0c;我们可以用 Python 编写一个炫彩夺目的烟花盛典。本文将详细介绍如何使用 Pygame 库创建一个令人惊叹的烟花效果。 一、效果图&#xff1a; 二…