Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5

 

For k = 3, you should return: 3->2->1->4->5
LeetCode: Reverse Nodes in k-Group 解题报告 
 
SOLUTION 1
用递归实现,逐层进行反转。遇到最后一个如果个数不为k,再反转一次即可。
 1 /*
 2     SOLUTION 2: A better rec version.
 3     */
 4     public ListNode reverseKGroup2(ListNode head, int k) {
 5         if (head == null) {
 6             return null;
 7         }        
 8         
 9         return rec2(head, k);
10     }
11     
12     public ListNode rec2(ListNode head, int k) {
13         if (head == null) {
14             return null;
15         }
16         
17         ListNode dummy = new ListNode(0);
18         
19         ListNode cur = head;
20         int cnt = 0;
21         while (cur != null) {
22             ListNode tmp = cur.next;
23             cur.next = dummy.next;
24             dummy.next = cur;
25             
26             cur = tmp;
27             
28             cnt++;
29             
30             // reverse a k group.
31             if (cnt == k) {
32                 // BUG 1: 
33                 head.next = rec2(tmp, k);
34                 return dummy.next;
35             }
36         }
37         
38         // we don't have k nodes.
39         if (cnt != k) {
40             cur = dummy.next;
41             dummy.next = null;
42             
43             // reverse again.
44             while (cur != null) {
45                 ListNode tmp = cur.next;
46                 cur.next = dummy.next;
47                 dummy.next = cur;
48                 
49                 cur = tmp;
50             }
51         }
52         
53         return dummy.next;
54     }
View Code

 

SOLUTION 2

另一个思路的递归:

先查看有没有k个node,如果有,切开2个链表,反转当前链表,并且使用递归处理下一个section,最后再把2者连接起来即可。

 1 public ListNode reverseKGroup1(ListNode head, int k) {
 2         if (head == null) {
 3             return null;
 4         }        
 5         
 6         return rec(head, k);
 7     }
 8     
 9     // Solution 1: Recursion.
10     public ListNode rec(ListNode head, int k) {
11         // Reverse k and link to the next section.
12         ListNode dummy = new ListNode(0);
13         dummy.next = head;
14         
15         // find the tail node of the section. If not find, just return.
16         int cnt = k;
17         ListNode tail = dummy;
18         while (cnt > 0 && tail != null) {
19             cnt--;
20             tail = tail.next;
21         }
22         
23         // We don't have k nodes to revers.
24         // bug 1: we should judge that if tail == null to avoid the overflow.
25         if (tail == null) {
26             return head;
27         }
28         
29         // cut the 2 list.
30         ListNode next = tail.next;
31         tail.next = null;
32         
33         // reverse the first list.
34         ListNode newHead = reverse(head);
35         
36         // reverse the next section.
37         next = rec(next, k);
38         
39         // link the 2 sections.
40         head.next = next;
41         
42         return newHead;
43     }
44     
45     public ListNode reverse(ListNode head) {
46         ListNode dummy = new ListNode(0);
47         while (head != null) {
48             ListNode tmp = head.next;
49             head.next = dummy.next;
50             dummy.next = head;
51             
52             head = tmp;
53         }
54         
55         return dummy.next;
56     }
View Code

相关文章: