24. 两两交换链表中的节点

题目描述

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

示例:

输入: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)。除了常数级别的变量,算法的空间复杂度是常数级别的。

你可能感兴趣的:(#,LeetCode,链表,数据结构,c#,c语言,leetcode)