1+ // 24. 两两交换链表中的节点
2+
3+
4+ /**
5+ * Definition for singly-linked list.
6+ * public class ListNode {
7+ * int val;
8+ * ListNode next;
9+ * ListNode() {}
10+ * ListNode(int val) { this.val = val; }
11+ * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
12+ * }
13+ */
14+
15+
16+ /*
17+ 递归:
18+ 1、方法功能:入参是一个节点,修改当前节点和下一节点指针方向,交换两个节点,返回新的头节点
19+ 2、终止条件:head或head.next为空则直接返回头节点,因为交换至少需要两个节点
20+ 3、返回结果:交换完成后新的头节点
21+ 4、递归逻辑:
22+ 1)两个节点交换完成后,新的尾节点连接着后续链表的头节点,而后续链表的头节点需要同样的交换操作,因此调用同样的方法递归处理
23+ 2)0个、1个节点的情况在终止条件中包含,单层递归时可以把链表当成只有2个或3个节点的简单情况,前两个节点交换完成后,连接着第三个节点newHead.next,
24+ newHead.next作为新的头节点,同样需要交换,因此调用同样的方法
25+
26+ 1 2 3 4
27+ ↑ ↑
28+ head newHead
29+ */
30+ class Solution {
31+ public ListNode swapPairs (ListNode head ) {
32+ if (head == null || head .next == null ) {
33+ return head ;
34+ }
35+ ListNode newHead = head .next ;
36+ head .next = swapPairs (newHead .next );
37+ newHead .next = head ;
38+ return newHead ;
39+ }
40+ }
41+
42+
43+ /*
44+ 递归:
45+ 思路同上。上一解法第三个节点用newHead.next获取,所以要先连接好第三个节点后,newHead.next指针才能移动。
46+ 本解法第三个节点直接用一个新的指针temp标记,所以可以先移动newHead.next指针,不会丢失第三个节点的引用。
47+
48+ 1 2 3 4
49+ ↑ ↑ ↑
50+ head newHead temp
51+ */
52+ class Solution {
53+ public ListNode swapPairs (ListNode head ) {
54+ if (head == null || head .next == null ) {
55+ return head ;
56+ }
57+ ListNode temp = head .next .next ;
58+ ListNode newHead = head .next ;
59+ newHead .next = head ;
60+ head .next = swapPairs (temp );
61+ return newHead ;
62+ }
63+ }
64+
65+
66+ /*
67+ 迭代:
68+ 1、多指针标记用到的节点
69+ 2、修改节点指针方向
70+ 3、重新初始化指针,标记下一次交换的节点
71+
72+ 0 1 2 3 4
73+ ↑ ↑ ↑
74+ root/pre start end
75+ ============================
76+ 0 2 1 3 4
77+ ↑ ↑ ↑ ↑
78+ root pre start end
79+ */
80+ class Solution {
81+ public ListNode swapPairs (ListNode head ) {
82+ ListNode root = new ListNode (0 , head );
83+ ListNode pre = root ;
84+ while (pre .next != null && pre .next .next != null ) {
85+ ListNode start = pre .next ;
86+ ListNode end = pre .next .next ;
87+ pre .next = end ;
88+ start .next = end .next ;
89+ end .next = start ;
90+ pre = start ;
91+ }
92+ return root .next ;
93+ }
94+ }
0 commit comments