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

news2024/11/20 10:25:35

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函数,处理剩余的节点,传入头【节点的下一个节点的下一个节点】,返回值赋值给tmp
            ListNode tmp = swapPairs(head.next.next);
            // 获取当前节点的下一个节点赋值给p
            ListNode 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 指针指向交换后的新节点 tmp
                pre.next = tmp;

                // 将 pre 移动到下一对相邻节点的前一个节点,即当前节点 cur
                pre = cur;
                // 将 cur 移动到下一对相邻节点的当前节点,即下一个节点
                cur = cur.next;
            }

            // 返回虚拟头节点 dummy 的 next,即完成相邻节点的交换后的链表
            return dummy.next;
        }
    }
代码解析
  • 算法通过维护一个虚拟头节点,利用两个指针 precur 在链表中遍历,不断交换相邻的节点。

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

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

图解

image

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

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

相关文章

使用Pygame显示文字的示例代码

import pygame import syspygame.init()# 设置窗口尺寸 win_size (800, 600) screen pygame.display.set_mode(win_size) pygame.display.set_caption("文字显示示例")# 设置字体和文字内容 font pygame.font.SysFont(None, 48) # 使用系统默认字体&#xff0c;字…

第十一章 Cookie

第十一章 Cookie 1.什么是Cookie2.Cookie的创建3.Cookie的获取4.Cookie值的修改5.谷歌浏览器和火狐浏览器如何查看Cookie6.Cookie的存活设置7.Cookie的path属性8.Cookie练习之免用户名登入 1.什么是Cookie 2.Cookie的创建 下面我看看如何创建Cookie&#xff0c;如何让客户端保…

极客时间-读多写少型缓存设计

背景 内容是极客时间-徐长龙老师的高并发系统实战课的个人学习笔记&#xff0c;欢迎大家学习&#xff01;https://time.geekbang.org/column/article/596644 总览内容如下&#xff1a; 缓存性价比 一般来说&#xff0c;只有热点数据放到缓存才更有价值 数据量查询频率命中…

67.网游逆向分析与插件开发-角色数据的获取-分析角色数据基址

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;角色类的数据分析与C还原-CSDN博客 基址这个东西说好找也好找&#xff0c;说不好找是真找不着&#xff0c;但就根据一个原则&#xff0c;就是确认这个东西有基址还是没基址&#xff0c;为什么会有没基…

STM32--基于STM32F103的MAX30102心率血氧测量

本文介绍基于STM32F103ZET6MAX30102心率血氧测量0.96寸OLED&#xff08;7针&#xff09;显示&#xff08;完整程序代码见文末链接&#xff09; 一、简介 MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块。它集成了一个红光LED和一个红外光LED、光电检测器、光器…

移动通信原理与关键技术学习之信道编解码(5)

先回顾调制的过程&#xff1a;调制就是对信号源的信息进行处理加到载波上&#xff0c;使其变为适合于信道传输的形式的过程&#xff0c;就是使载波随信号而改变的技术。 1.什么是IQ调制&#xff1f; 答&#xff1a;将数据分为两路&#xff0c;分别进行载波调制&#xff0c;两…

Camunda Sub Process

一&#xff1a;内嵌子流程 repositoryService.createDeployment().name("内嵌子流程").addClasspathResource("bpmn/embed_sub_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance processInstance …

教你三招该如何制作家具样本册

​随着生活品质的提高&#xff0c;人们对家居装饰的要求也越来越高。家具作为家居装饰的重要组成部分&#xff0c;其选择和搭配也显得尤为重要。为了更好地展示家具的特点和风格&#xff0c;制作家具样本册成为了许多人的选择。那么&#xff0c;如何制作一份精美的家具样本册呢…

Day31 贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和

贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和 理论基础&#xff08;转载自代码随想录&#xff09; 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#…

CMake入门教程【实战篇】使用Boost库

文章目录 安装 Boost 库CMake中使用Boost库时安装 Boost 库 下载地址 https://www.boost.org/users/download/ 下载版本 选择二进制版本或者源码 二进制版本直接安装即可 源码版本编译->安装 解压到本地目录,如e:/dev/。运行E:\dev\boost_1_83_0\bootstrap.bat,会在同目录下…

激活/注册navicat15

一、获取软件 链接&#xff1a;https://pan.baidu.com/s/1F_tiLuLvVFMEz8pDfIvDjw?pwdjjfj 提取码&#xff1a;jjfj 二、安装 安装的过程我就不放了&#xff0c;重点如下 安装完不要打开软件&#xff01; 安装完不要打开软件&#xff01; 安装完不要打开软件&#xff01;…

Spark SQL进阶

DataFrame详解 清洗相关API 去重API 删除空缺值的API 替换缺失值的API from pyspark import SparkConf, SparkContext import os from pyspark.sql import SparkSession# 绑定指定的Python解释器 os.environ[SPARK_HOME] /export/server/spark os.environ[PYSPARK_PYTHON]…

前端面试题集合六(高频)

1、vue实现双向数据绑定原理是什么&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…

RT-Thread入门笔记3-线程的创建

线程 RT-Thread 中&#xff0c;线程由三部分组成&#xff1a;线程代码&#xff08;入口函数&#xff09;、线程控制块、线程堆栈. 线程代码: 线程控制块 : 线程控制块是操作系统用于管理线程的一个数据结构&#xff0c; 它会存放线程的一些信息&#xff0c; 例如优先级、 线程…

从学习投研流程的角度学习Qlib

许多同学只是把Qlib当做一个简单的工具来学习。其实Qlib隐含了一套正规的投研流程&#xff0c;从投研流程的视角去学习Qlib,则不仅能加深对Qlib的理解&#xff0c;而且能够掌握正确的投研流程&#xff0c;哪怕以后不使用Qlib而是使用其他系统了&#xff0c;这套流程还是适用的。…

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…

创建EasyCodeMybatisCodeHelperPro模板文件用于将数据库表生成前端json文件

在intellij idea中&#xff0c;通过插件EasyCodeMybatisCodeHelperPro&#xff0c;从现有的模板文件中选择一个复制粘贴&#xff0c;然后稍为修改&#xff0c;即可得到一个合适的模板文件。 现在的前端&#xff0c;越来越像后端。TypeScript替代了JavaScript&#xff0c;引入了…

基于Flask的高并发部署方案

文章目录 Flask方案简介服务端代码客户端代码 Gevent Flask方案简介安装示例 gunicornFlask 部署服务简介安装示例 在AI部署方案中&#xff0c;Flask是最常用的方案&#xff01;本文列举几种最常用基于Flask的部署方案。 Flask方案 简介 Flask 是一个轻量级的 Python Web 框架…

微信小程序swiper实现层叠轮播图

在微信小程序中,需要实现展示5个&#xff0c;横向层叠的轮播图效果&#xff0c;轮播图由中间到2侧的依次缩小.如下图 使用原生小程序进行开发,没有使用Skyline模式&#xff0c;所以layout-type配置项也无效。所以基于swiper组件进行调整。 主要思路就是设置不同的样式&#xff…