链表 - 两两交换链表中的节点

链表 - 两两交换链表中的节点

这里我们以力扣24题为例,讲讲如何将相邻的两个节点进行交换

从官方给的示例和我的示例就可以发现:链表的节点数是奇数时最后一个节点交换,是偶数时最后一个节点需要交换

在这里我们还是要用虚拟头节点

接下来我们来梳理下循环中的操作步骤

  1. current节点初始化成虚拟头节点
  2. current节点的Next直接指向第三个节点(包括虚拟头节点)
  3. 第三个节点的Next指向第二个节点
  4. 第二个节点的Next指向第四个节点
  5. current节点指向第二个节点

注意:上述步骤梳理,以虚拟头节点为第一个节点;所说的第几个节点都是按照原始链表的顺序。

在上述步骤梳理中,还是有很多细节的。

  1. 如果虚拟头节点的Next指向第三个节点,就表示第一个节点和第二个节点之间的联系断了
  2. 如果第三个节点的Next指向第二个节点,就表示第三个节点和第四个节点之间的联系断了

所以我们在开始交换之前将第二个节点和第四个节点缓存起来。

好,循环体内交换逻辑梳理出来了,那循环条件是什么呢?

文章最开始,我们说了,奇数个节点和偶数个节点的处理是不一样的。又加上我们使用了虚拟头节点,最后总结出循环条件是`current.Next != nil && current.Next.Next != nil`

  • 当我们的节点数是偶数,到最后一个节点就停止,最后一个节点的特征是他的Next = nil
  • 当我们的节点数是奇数,到倒数第二个节点就停止,此时current就是落在倒数第二个节点上,此时他的特征就是Next.Next = nil

接下来我们就用代码实现了

go 复制代码
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func swapPairs(head *ListNode) *ListNode {
    // 构建虚拟头节点
    dummy := &ListNode{
        Next: head,
    }
    current := dummy // 从虚拟头节点开始
    // 控制好循环条件,必须是这个顺序,否则会报空指针异常
    // 其实很好理解,父节点都没有,哪里有子节点
    for current.Next != nil && current.Next.Next != nil {
        temp1 := current.Next // 记录第二个节点
        temp2 := current.Next.Next.Next // 记录第四个节点
        current.Next = current.Next.Next
        current.Next.Next = temp1
        temp1.Next = temp2
        current = temp1 // 这一步需要好好理解下
    }
    return current.Next // 因为我们加上了虚拟头节点,所以最后返回的结果需要去除这个节点
}
相关推荐
Oneslide2 小时前
ubuntu 手动安装claude
后端
GetcharZp10 小时前
玩转 Linux 机器视觉:手把手带你搞定 Ubuntu 下海康工业相机 C++ SDK
后端
星星在线13 小时前
MusicFree:一个「All in One」的个人音乐服务器,让听歌回归简单
前端·后端
IT_陈寒14 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
demo007x15 小时前
Docling 文档转换以及技术架构分析
前端·后端·程序员
袋鱼不重16 小时前
我的神奇同事,AI 用多了居然写了个 Open In Codex
前端·后端·ai编程
用户83562907805116 小时前
使用 Python 操作 Word 内容控件
后端·python
像我这样帅的人丶你还16 小时前
啥? 前端也要会干Java?🛵🛵🛵
后端
Hommy8816 小时前
【剪映小助手】添加贴纸接口(Add Sticker)
后端·github·剪映小助手·视频剪辑自动化·剪映api
通信小呆呆16 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人