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

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

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

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

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

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

  1. current\]节点初始化成虚拟头节点

  2. 第三个节点的Next指向第二个节点
  3. 第二个节点的Next指向第四个节点
  4. 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 // 因为我们加上了虚拟头节点,所以最后返回的结果需要去除这个节点
}
相关推荐
焦耳加热3 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
wan5555cn3 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u6063 小时前
常用排序算法核心知识点梳理
算法·排序
程序员爱钓鱼4 小时前
Go语言实战案例 — 工具开发篇:实现一个图片批量压缩工具
后端·google·go
蒋星熠6 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
ChinaRainbowSea6 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
舒一笑6 小时前
同步框架与底层消费机制解决方案梳理
后端·程序员
minh_coo6 小时前
Spring框架事件驱动架构核心注解之@EventListener
java·后端·spring·架构·intellij-idea
小欣加油6 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展
3Cloudream6 小时前
LeetCode 003. 无重复字符的最长子串 - 滑动窗口与哈希表详解
算法·leetcode·字符串·双指针·滑动窗口·哈希表·中等