题意:把原始链表k个k个的反转,如果最后剩余的不到k个结点,那么保持不变。
例子:
给定链表: 1->2->3->4->5
如果 k = 2, 返回链表: 2->1->4->3->5
如果 k = 3, 返回链表: 3->2->1->4->5
分析:前两天十大上有师兄分享17年算法岗面经时提到了本题,因此在做本题的时候也格外认真。晚上洗澡的时候理了一下思路,然后手写代码bug-free,还是很开心的。
题目本身是几道题的综合,因此只要前面的链表题好好做了,包括Reverse Linked List II和Swap Nodes in Pairs。下面讲一下思路:
首先定义几个指针。
老规矩dummyNode指向头节点的前置节点,因为有可能涉及到头节点的操作。
checkNode用来检查是否剩余的有k个节点,当不足k个节点时,直接返回dummyNode.next。
pre、left和right和Reverse Linked List II中的作用相同,用来Reverse节点。
那么对于链表1->2->3->4->5来说,翻转过程如下:
1->2->3->4->5
2->1->3->4->5
3->2->1->4->5
因此代码为:
class Solution {
public static ListNode reverseKGroup(ListNode head, int k) {
if(head == null || head.next == null) return head;
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode pre = dummyNode;
ListNode left = head;
ListNode right = head.next;
ListNode checkNode = head;
while(true){
for(int i = 0; i < k; i++){
if(checkNode == null){
return dummyNode.next;
}
checkNode = checkNode.next;
}
for(int i = 0; i < k - 1; i++){
left.next = right.next;
right.next = pre.next;
pre.next = right;
right = left.next;
}
pre = left;
left = right;
// right 有可能是空节点
if(right == null){
return dummyNode.next;
}else{
right = right.next;
}
}
}
public static void print(ListNode head){
while(head != null){
System.out.println(head.val);
head = head.next;
}
}
public static void main(String[] args) {
ListNode l1 = new ListNode(1);
ListNode l2 = new ListNode(2);
ListNode l3 = new ListNode(3);
ListNode l4 = new ListNode(4);
ListNode l5 = new ListNode(5);
//
//
//
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
print(reverseKGroup(l1, 2));
}
}