打字猫

LeetCode从算法到算命—24.两两交换链表中的节点(20230806)

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

题目信息

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

示例 1:

image

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

示例 2:

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

示例 3:

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

提示:

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

解题思路

在不修改值的情况下完成本题,也就是不能把整个链表每个值放到集合里,在集合中两两交换后再构建为一个新的链表。我们需要直接对节点本身进行交换,而不能改变每个节点的值。

每次只交换两个节点,假设这样一个链表1 -> 2 -> 3 -> 4 -> 5,交换一次之后就会变成2 -> 1 3 -> 4 -> 5,再接下来交换以3开头的链表2 -> 1 4 -> 3 5,最后以5开头的链表后面是没有元素的,也就是无法交换的。交换完之后把它们连起来,就是最后的答案了,因此这道题目可以用递归来解决。

指针的变化情况是,第一次交换的时候,二号节点指向一号节点,也就是Node2.next指向Node1;一号节点没有指向二号节点,而是以三号节点为开头的链表交换后的结果(交换后是返回一个头节点来表示整个链表),因此Node1应该指向swap(Node3)。那么重复这个过程就能达到两两节点交换的效果,最后返回二号节点(因为交换后二号节点就会变成整个链表的头节点)就可以了。

Java代码

public class Solution {
    public class ListNode {
      int val;
      ListNode next;
      ListNode() {}
      ListNode(int val) { this.val = val; }
      ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  }

    public ListNode swapPairs(ListNode head) {
        //如果链表没有节点了或者只剩一个节点,就不用交换了,直接返回当前节点
        if (head == null || head.next == null) {
            return head;
        }
        //定义三个节点
        ListNode node1 = head;
        ListNode node2 = node1.next;
        ListNode node3 = node2.next;
        //两两交换中,原第二个节点指向第一个节点
        node2.next = node1;
        //两两交换中,原第一个节点指向三号节点->以三号节点开头的链表交换后的结果
        node1.next = swapPairs(node3);
        //最后返回node2
        return node2;
    }

}
posted @ 2023-08-07 00:27  我还是我吗?  阅读(5)  评论(0编辑  收藏  举报