链表 - 24. 两两交换链表中的节点(C#和C实现)

链表 - 24. 两两交换链表中的节点(C#和C实现)

题目描述

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

示例:

输入:1->2->3->4
输出:2->1->4->3

解题思路

使用迭代或递归的方式来实现两两交换链表中的节点。

解题步骤

迭代方法:

  1. 初始化一个虚拟头节点 dummy,使其 next 指向链表的头节点。
  2. 初始化指针 prev,初始指向虚拟头节点。
  3. 使用循环遍历链表,每次交换两个节点,更新 prevnext 指针,直到遍历完整个链表。

递归方法:

  1. 使用递归实现两两交换链表中的节点,递归的终止条件是当前节点为 null 或者 next 节点为 null
  2. 在递归过程中,交换当前节点和下一个节点,并递归调用下下个节点。
  3. 返回新的头节点。

C#代码实现(迭代方法)

public ListNode SwapPairs(ListNode head) {
    // 创建一个虚拟节点,指向head
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    // 创建一个前一个节点,指向虚拟节点
    ListNode prev = dummy;

    // 当前一个节点和它的下一个节点都不为空时,进行交换
    while (prev.next != null && prev.next.next != null) {
        // 创建两个节点,分别指向前一个节点和它的下一个节点
        ListNode first = prev.next;
        ListNode second = prev.next.next;

        // 将第一个节点的指针指向第二个节点的指针指向的节点
        first.next = second.next;
        // 将第二个节点的指针指向第一个节点
        second.next = first;
        // 将前一个节点的指针指向第二个节点
        prev.next = second;

        // 将前一个节点指向第一个节点
        prev = first;
    }

    // 返回虚拟节点的下一个节点
    return dummy.next;
}

C代码实现(迭代方法)

struct ListNode* swapPairs(struct ListNode* head) {
    // 创建一个虚拟头节点
    struct ListNode* dummy = malloc(sizeof(struct ListNode));
    dummy->next = head;
    // 创建一个前一个节点
    struct ListNode* prev = dummy;

    // 当前一个节点下一个节点不为空,且下下个节点不为空时,进行交换
    while (prev->next != NULL && prev->next->next != NULL) {
        // 创建两个节点,分别指向前一个节点下一个节点和下下个节点
        struct ListNode* first = prev->next;
        struct ListNode* second = prev->next->next;

        // 将第一个节点指向下下个节点
        first->next = second->next;
        // 将第二个节点指向第一个节点
        second->next = first;
        // 将前一个节点指向第二个节点
        prev->next = second;

        // 将前一个节点指向第一个节点
        prev = first;
    }

    // 返回虚拟头节点的下一个节点
    return dummy->next;
}

C#代码实现(递归方法)

public ListNode SwapPairs(ListNode head) {
    // 如果链表为空或者只有一个节点,则直接返回
    if (head == null || head.next == null) {
        return head;
    }

    // 定义一个新的头节点,用来保存交换后的链表
    ListNode newHead = head.next;
    // 将头节点的下一个节点作为头节点,进行递归调用
    head.next = SwapPairs(head.next.next);
    // 将新的头节点的下一个节点指向头节点
    newHead.next = head;

    // 返回新的头节点
    return newHead;
}

C代码实现(递归方法)

struct ListNode* swapPairs(struct ListNode* head) {
    // 如果链表为空或者只有一个节点,直接返回
    if (head == NULL || head->next == NULL) {
        return head;
    }

    // 保存第二个节点
    struct ListNode* newHead = head->next;
    // 将head的next指向下一个节点的next,即指向第二个节点
    head->next = swapPairs(head->next->next);
    // 将第二个节点的next指向head,即指向第一个节点
    newHead->next = head;

    return newHead;
}

时间复杂度和空间复杂度

  • 时间复杂度:O(n),其中 n 是链表的长度。每个节点最多被访问一次。
  • 空间复杂度:O(1)。除了常数级别的变量,算法的空间复杂度是常数级别的。

参与点评

读者朋友们,如果您在阅读过程中,对文章的质量、易理解性有任何建议,欢迎在评论区指出,我会认真改进。

  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AmHardy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值