这道题是在一个List里面每k个node为一个group,然后反转。这里有几个要点,1.判断这个group能不能翻转,如果group的个数小于k,则不翻转),2. 翻转list,leetcode 206,3. 翻转之后与前后group要链接上,并且进行下一个group的翻转。整道题思路简单,但是容易出错,特别是在第3步,所以这是一道hard的题,难就难在细节的地方。
代码如下:
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 public class Solution { 10 public ListNode reverseKGroup(ListNode head, int k) { 11 if (k <= 1) return head; 12 ListNode dumpNode = new ListNode(0); 13 dumpNode.next = head; 14 ListNode curr = dumpNode; 15 //用tail尝试走到第k个来判断这个group是否能翻转 16 ListNode tail = dumpNode.next; 17 //count来计数。 18 int count = k; 19 while (tail != null) { 20 //tail往后走k步,如果可以翻转,则count一定等于0; 21 while (tail != null && count != 0) { 22 tail = tail.next; 23 count--; 24 } 25 //如果count不为0,则说明group的数目少于k(tail已走到尾) 26 if (count != 0) return dumpNode.next; 27 else { 28 //反转group,此时,tail指向下个group的头(使得group能链接下一个group) 29 ListNode temp = reverseList(curr.next,tail); 30 //curr在dump上或者上一个group的尾部,使得curr能连上该group。 31 curr.next = temp; 32 count = k; 33 //移动curr,使它到达刚反转的group的底部。 34 while (count-- != 0) { 35 curr = curr.next; 36 } 37 //tail指向下个group的头,准备下个循环。 38 tail = curr.next; 39 //count重新归k。 40 count = k; 41 } 42 } 43 return dumpNode.next; 44 } 45 46 //反转linked list,tail为下个list的头,不能理解下面的代码在纸上写一遍就好。 47 public ListNode reverseList(ListNode head, ListNode tail) { 48 ListNode prev = tail; 49 while (head != tail) { 50 ListNode temp = head.next; 51 head.next = prev; 52 prev = head; 53 head = temp; 54 } 55 return prev; 56 } 57 }