K个节点的组内逆序调整
给定一个单链表的头节点head,和一个正数k
实现k个节点的小组内部逆序,如果最后一组不够k个就不调整。
例子:
调整前:1->2->3->4->5->6->7->8, k=3
调整后:3->2->1->6->5->4->7->8
代码实现:
1 package com.cy.class04; 2 3 /** 4 * 测试连接:https://leetcode.com/problems/reverse-nodes-in-k-group/ 5 */ 6 public class Code04_ReverseNodesInKGroup { 7 8 // 不要提交这个类 9 public static class ListNode { 10 public int val; 11 public ListNode next; 12 } 13 14 public static ListNode reverseKGroup(ListNode head, int k) { 15 ListNode start = head; 16 ListNode end = getKGroupEnd(start, k); 17 //第一组都没有凑齐都不用逆序了直接返回老head 18 if (end == null) { 19 return head; 20 } 21 22 //后面该怎么调整怎么调整,这个head就是要返回的,不要动它了。 23 head = end; 24 reverse(start, end); 25 //lastEnd:上一组的结尾节点 26 ListNode lastEnd = start; 27 while (lastEnd.next != null) { 28 start = lastEnd.next; 29 end = getKGroupEnd(start, k); 30 if (end == null) { 31 return head; 32 } 33 reverse(start, end); 34 lastEnd.next = end; 35 lastEnd = start; 36 } 37 return head; 38 } 39 40 /** 41 * 给定链表的开始节点,数够k个,把数到的节点返回 42 * 该组内元素不够k个,就返回null 43 */ 44 public static ListNode getKGroupEnd(ListNode start, int k) { 45 while (--k != 0 && start != null) { 46 start = start.next; 47 } 48 return start; 49 } 50 51 public static void reverse(ListNode start, ListNode end) { 52 end = end.next; 53 ListNode pre = null; 54 ListNode cur = start; 55 ListNode next = null; 56 while (cur != end) { 57 next = cur.next; 58 cur.next = pre; 59 pre = cur; 60 cur = next; 61 } 62 start.next = end; 63 } 64 }
演算草图:

思路是什么?
1.假设链表分成了三组:a~b,c~d,e~f,假如第二组逆序好了成了d~c,第一组逆序好了成了b~a,第三组逆序好了成了f~e,那么就要修改指向:将a的next指向d,c的next指向f。
getKGroupEnd函数:给定一个开始节点,数到k个,返回这个最后数到的节点,其实就是从start开始返回第k个节点。


这里面其实是有边界条件考虑的,因为可能该组内元素个数不满k个,就数到null了:

reverse方法解释:

经过reverse之后变成:

s之前的是啥,不管。从s开始。将a~d之间进行逆序:

最后逆序完成的效果见下图:而且逆序完成之后,a已经指向f了,但是没有任何节点指向a。

画图工具可以复现这个逆序过程:

reverseKGroup方法的解释:
草图1:

运行到head = end时,这个head就是要返回的,变成这样:

运行到24行,reverse(start, end)时变成这样:

此时,a - b - c这组的结尾节点就是start,即a节点。
27行:上组结尾节点a的下个节点不为null,进入while循环。28行:start来到d节点,见下图:

30行:end为f节点,不为null,进入33行:reverse(start, end),变成如下:

运行到34行:lastEnd.next = end;将上组的末尾节点的下个节点指向修改,a本来是指向d的,改成了a指向f:

并且lastEnd来到d节点:

继续运行,g、h不够k=3个,end为null,直接返回head,while循环中断,也就是返回c节点,程序结束。
什么时候会while循环完毕,执行到最后return head结束呢?----所有节点个数正好是k的整数倍。
总结:
1.该题在leetcode中属于难度级别hard,很麻烦,要对于整个函数的设计能力非常强才行。
2.先想好整个过程,然后再是把想法变成code,其实挺难的。它不在于算法,而是在于你的coding能力强不强。
---
浙公网安备 33010602011771号