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

  1. 24.两两交换链表中的节点
    1. 24.1 题目
    2. 24.2 题解
      1. 递归交换节点
      2. 迭代交换节点
    3. 24.3 代码
    4. 24.4 运行结果

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


24.1 题目

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

24.2 题解

递归交换节点

// 方法一:递归交换节点
static ListNode SwapPairs1(ListNode head)
{
    // 如果链表为空或者只有一个节点,直接返回
    if (head == null || head.next == null)
    {
        return head;
    }

    // 交换相邻的两个节点
    ListNode first = head;
    ListNode second = head.next;

    // 递归地对剩余节点进行相邻交换
    first.next = SwapPairs1(second.next);
    second.next = first;

    // 返回交换后的头节点
    return second;
}

迭代交换节点

// 方法二:迭代交换节点
static ListNode SwapPairs2(ListNode cur)
{
    // 创建虚拟头节点,简化操作
    ListNode dummy = new ListNode(0);
    dummy.next = cur;
    ListNode prev = dummy;

    // 当还有至少两个相邻节点时继续交换
    while (cur != null && cur.next != null)
    {
        // 记录要交换的两个节点
        ListNode first = cur;
        ListNode second = cur.next;

        // 实现交换
        prev.next = second;
        first.next = second.next;
        second.next = first;

        // 移动到下一对节点
        prev = first;
        cur = first.next;
    }

    // 返回交换后的链表头
    return dummy.next;
}

24.3 代码

using System;

// 链表节点定义
public class ListNode
{
    public int val;
    public ListNode next;

    public ListNode(int val = 0, ListNode next = null)
    {
        this.val = val;
        this.next = next;
    }
}

class Program
{
    static void Main()
    {
        #region 题目

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

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

        // 示例 2:
        // 输入:head = []
        // 输出:[]

        // 示例 3:
        // 输入:head = [1]
        // 输出:[1]

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

        #endregion

        #region 测试

        // 示例 1 测试
        ListNode head1 = GenerateList(new int[] { 1, 2, 3, 4 });
        Console.Write("示例1 方法1 输出:");
        PrintList(head1);
        ListNode swappedHead1 = SwapPairs1(head1);
        Console.Write(" --> ");
        PrintList(swappedHead1);

        ListNode head1_2 = GenerateList(new int[] { 1, 2, 3, 4 });
        Console.Write("示例1 方法2 输出:");
        PrintList(head1_2);
        ListNode swappedHead1_2 = SwapPairs2(head1_2);
        Console.Write(" --> ");
        PrintList(swappedHead1_2);

        // 示例 2 测试
        ListNode head2 = GenerateList(new int[] { });
        Console.Write("示例2 方法1 输出:");
        PrintList(head2);
        ListNode swappedHead2 = SwapPairs1(head2);
        Console.Write(" --> ");
        PrintList(swappedHead2);

        ListNode head2_2 = GenerateList(new int[] { });
        Console.Write("示例2 方法2 输出:");
        PrintList(head2_2);
        ListNode swappedHead2_2 = SwapPairs2(head2_2);
        Console.Write(" --> ");
        PrintList(swappedHead2_2);

        // 示例 3 测试
        ListNode head3 = GenerateList(new int[] { 1 });
        Console.Write("示例3 方法1 输出:");
        PrintList(head3);
        ListNode swappedHead3 = SwapPairs1(head3);
        Console.Write(" --> ");
        PrintList(swappedHead3);

        ListNode head3_2 = GenerateList(new int[] { 1 });
        Console.Write("示例3 方法2 输出:");
        PrintList(head3_2);
        ListNode swappedHead3_2 = SwapPairs2(head3_2);
        Console.Write(" --> ");
        PrintList(swappedHead3_2);

        #endregion
    }

    #region 答案

    // 方法一:递归交换节点
    static ListNode SwapPairs1(ListNode head)
    {
        // 如果链表为空或者只有一个节点,直接返回
        if (head == null || head.next == null)
        {
            return head;
        }

        // 交换相邻的两个节点
        ListNode first = head;
        ListNode second = head.next;

        // 递归地对剩余节点进行相邻交换
        first.next = SwapPairs1(second.next);
        second.next = first;

        // 返回交换后的头节点
        return second;
    }

    // 方法二:迭代交换节点
    static ListNode SwapPairs2(ListNode cur)
    {
        // 创建虚拟头节点,简化操作
        ListNode dummy = new ListNode(0);
        dummy.next = cur;
        ListNode prev = dummy;

        // 当还有至少两个相邻节点时继续交换
        while (cur != null && cur.next != null)
        {
            // 记录要交换的两个节点
            ListNode first = cur;
            ListNode second = cur.next;

            // 实现交换
            prev.next = second;
            first.next = second.next;
            second.next = first;

            // 移动到下一对节点
            prev = first;
            cur = first.next;
        }

        // 返回交换后的链表头
        return dummy.next;
    }

    #endregion

    #region 辅助方法

    // 根据数组生成链表
    static ListNode GenerateList(int[] nums)
    {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        foreach (var num in nums)
        {
            current.next = new ListNode(num);
            current = current.next;
        }

        return dummy.next;
    }

    // 打印链表
    static void PrintList(ListNode head)
    {
        while (head != null)
        {
            Console.Write(head.val + " ");
            head = head.next;
        }

        Console.WriteLine();
    }

    #endregion
}

24.4 运行结果

示例1 方法1 输出:1 2 3 4 
 --> 2 1 4 3 
示例1 方法2 输出:1 2 3 4 
 --> 2 1 4 3 
示例2 方法1 输出:
 --> 
示例2 方法2 输出:
 --> 
示例3 方法1 输出:1 
 --> 1 
示例3 方法2 输出:1 
 --> 1 


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏