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

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

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

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例1 :

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

示例 2:

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

示例 3:

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

提示:

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

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

本题可以分为递归方法和迭代方法。首先来看递归方法,我们需要明确每一步做什么,无非就是两个节点颠倒顺序,假设当前节点为head,下一个节点为newNode = head.next,每次交换完成后,newNode成为队列的第一个节点,head成为队列的第二个节点。判断结束的条件就是当前节点为空或者当前节点的下一个节点为空。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Definition for singly-linked list.
* 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; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode newNode = head.next;

head.next = swapPairs(newNode.next);
newNode.next = head;
return newNode;
}
}

这道题用递归有点绕,我们来看下迭代的方式如何操作。一看到题目最直观的想法就是两个指针指向当前节点和下一个节点,然后交换,指针指向下一对进行交换即可。这里我们需要用到一个哑结点和一个临时指针(如果不额外加入会造成链表连不上的情况)。让dummy.next = head; temp = dummy,首先temp.next.next = q,即让temp的下一个节点为交换元素中的第二个位置上的元素q,这样交换完成后q变到第一个位置,p变为第二个位置,而dummy指向了q,即将链表连接了起来,最后让temp指向p即可。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* Definition for singly-linked list.
* 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; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null)
return head;

ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode temp = dummy;

while (temp.next != null && temp.next.next != null) {
ListNode p = temp.next;
ListNode q = temp.next.next;

temp.next = q;
p.next = q.next;
q.next = p;
temp = p;
}

return dummy.next;
}
}

Comments