当前位置: 首页 > article >正文

每日一题——两两交换链表中的节点

以下是整理成详细CSDN文档的格式,用于解释如何两两交换链表中的节点:


两两交换链表中的节点

    • 题目描述
    • 示例
      • 示例 1
      • 示例 2
      • 示例 3
    • 提示
    • 初始思路
    • 代码实现
    • 参考官方教程思路
    • 总结

题目描述

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

示例

示例 1

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

示例 2

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

示例 3

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

提示

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

初始思路

对于这个问题,我们可以通过迭代的方式进行节点交换。首先检查当前节点和下一个节点是否存在,如果存在,则交换这两个节点。然后继续检查下一个节点对,直到链表结束。

代码实现

以下是使用C语言实现的代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* swapPairs(struct ListNode* head) {
    // 如果链表为空或者只有一个节点,不需要交换,直接返回头节点
    if (head == NULL || head->next == NULL) {
        return head;
    }
    
    // 初始化first指针指向第一个节点,second指针指向第二个节点
    struct ListNode* first = head;
    struct ListNode* second = head->next;
    
    // third指针指向第二个节点的下一个节点,即下一个待交换的节点对中的第一个节点
    struct ListNode* third = head->next->next;
    
    // 交换first和second节点:将first的next指向third,second的next指向first,然后更新头节点为second
    first->next = third;
    second->next = first;
    head = second;

    // 初始化current指针,用于遍历链表,寻找需要交换的节点对
    struct ListNode* current = first;
    
    // 遍历链表,交换节点对
    while (current->next != NULL && current->next->next != NULL) {
        // 定位到下一个需要交换的节点对
        first = current->next;
        second = current->next->next;
        third = second->next; // third指向second的下一个节点
        
        // 执行节点交换:将current的next指向second,first的next指向third,second的next指向first
        current->next = second;
        first->next = third;
        second->next = first;
        
        // 移动current指针到下一个节点对的第一个节点,继续循环
        current = first;
    }
    
    // 返回交换后的链表头节点
    return head;
}

参考官方教程思路

为了简化问题,我们可以使用一个虚拟头节点(dummy head),这样可以使边界情况的处理更加简单。以下是使用C语言实现的代码:

#include <stdlib.h> // 引入stdlib.h头文件以使用malloc函数

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* swapPairs(struct ListNode* head) {
    // 创建一个虚拟头节点dummyHead,其next指向实际的头节点head
    // 使用虚拟头节点可以简化对头节点交换的处理
    struct ListNode* dummyHead = malloc(sizeof(struct ListNode)); // 动态分配内存
    dummyHead->next = head; // 将虚拟头节点的next指向实际的头节点
    struct ListNode* temp = dummyHead; // 使用temp指针遍历链表

    // 遍历链表,寻找需要交换的节点对
    while (temp->next != NULL && temp->next->next != NULL) {
        // first指向当前节点对的第一个节点
        struct ListNode* first = temp->next;
        // second指向当前节点对的第二个节点
        struct ListNode* second = temp->next->next;
        
        // 交换节点对的步骤:
        // 1. 将temp的next指向second,即当前节点对的第二个节点
        temp->next = second;
        // 2. 将first的next指向second的next,即跳过second,指向下一个节点对的第一个节点
        first->next = second->next;
        // 3. 将second的next指向first,完成两个节点的交换
        second->next = first;
        
        // 将temp向前移动到下一个节点对的第一个节点,继续循环
        temp = first;
    }
    
    // 返回虚拟头节点的下一个节点,即交换后的链表头节点
    // 由于dummyHead是一个虚拟节点,不包含在最终的链表中,所以返回dummyHead->next
    return dummyHead->next;
}


注意:在使用malloc函数时,需要确保在程序结束前释放分配的内存,以避免内存泄漏。在这个函数中,由于dummyHead是一个局部变量,它的内存会在函数返回后自动释放。

总结

通过以上代码,我们可以成功地两两交换链表中的节点。这个问题主要考察了链表的操作和指针的使用,通过迭代的方式可以方便地实现节点的交换。


http://www.kler.cn/a/582414.html

相关文章:

  • 【实战ES】实战 Elasticsearch:快速上手与深度实践-8.1.1基于ES的语义搜索(BERT嵌入向量)
  • Spring Boot集成EasyExcel
  • 自学Java-Java高级技术(单元测试、反射、注解、动态代理)
  • wps word 正文部分段前段后间距调整无用
  • libpcap捕捉过滤wifi beacon包解析国标飞行器drone id报文
  • 【python-uiautomator2】手机上的ATX应用界面报错问题处理:无法提供服务,非am instrument启动
  • Percona XtraBackup8.0备份实例
  • 如何保证Redis与MySQL双写一致性?分布式场景下的终极解决方案
  • 免费的模型效果编辑器推荐
  • 在Selenium中,driver.close和driver.quit之间有什么区别?分别在什么时候用?
  • docker jar镜像打包
  • std::ranges::views::common, std::ranges::common_view
  • 七大常用智能家居协议对比
  • 双周报Vol.67: 模式匹配支持守卫、LLVM 后端发布、支持 Attribute 语法...多项核心技术更新!
  • Word 小黑第2套
  • 【记录】LaTex|ACM单双栏混合排版出现大量空白的调整方式(例如附带单栏的附录)
  • MySQL Binlog的样式
  • 人工智能驱动数字孪生城市的实践探索
  • 展望 AIGC 前景:通义万相 2.1 与蓝耘智算平台共筑 AI 生产力高地
  • 六、OpenGL中EBO的使用及本质