📌  相关文章
📜  通过改变指针成对交换链表的相邻节点 | 2套(1)

📅  最后修改于: 2023-12-03 15:42:02.525000             🧑  作者: Mango

通过改变指针成对交换链表的相邻节点

在链表操作中,经常需要进行节点的交换,而成对交换相邻节点是其中一种常见的操作。这种操作可以通过改变指针来完成,本文将介绍两种实现方式。

方法一:迭代

迭代方法通过遍历链表,成对交换相邻节点的指针。算法步骤如下:

  1. 如果链表为空或者链表只有一个节点,则直接返回原链表;
  2. 定义一个虚拟节点dummy作为头结点,将其指向链表的头结点head,并初始化指针prev为虚拟节点;
  3. 对于每对相邻节点ab,交换它们的指针,"prev --> a --> b"变成"prev --> b --> a";
  4. 将指针prev移动到下一对相邻节点的前一个节点,继续步骤3,直到整个链表都被遍历完。

Python代码实现如下:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def swapPairs(head: ListNode) -> ListNode:
    dummy = ListNode(0)
    dummy.next = head
    prev = dummy
    while prev.next and prev.next.next:
        a = prev.next
        b = a.next
        prev.next, b.next, a.next = b, a, b.next
        prev = a
    return dummy.next

Java代码实现如下:

public class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        while (prev.next != null && prev.next.next != null) {
            ListNode a = prev.next;
            ListNode b = a.next;
            prev.next = b;
            a.next = b.next;
            b.next = a;
            prev = a;
        }
        return dummy.next;
    }
}

以上代码均通过LeetCode测试。

方法二:递归

递归方法通过递归交换相邻节点的指针,实现链表成对交换。算法步骤如下:

  1. 如果链表为空或者链表只有一个节点,则直接返回原链表;
  2. 将当前节点head和下一个节点next交换指针,递归调用函数对下一个节点的下一个节点递归调用此函数,将返回值作为当前节点的下一个节点;
  3. 返回当前节点。

Python代码实现如下:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def swapPairs(head: ListNode) -> ListNode:
    if not head or not head.next:
        return head
    next = head.next
    head.next = swapPairs(next.next)
    next.next = head
    return next

Java代码实现如下:

public class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode next = head.next;
        head.next = swapPairs(next.next);
        next.next = head;
        return next;
    }
}

以上代码均通过LeetCode测试。

性能比较

两种方法的时间复杂度均为O(n),但递归方法需要额外的空间来保存函数调用栈,因此空间复杂度要高于迭代方法。具体应用时,可以根据具体情况选择合适的方法。