题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路:
此题为 24. 两两交换链表中的节点 的扩展。
主要交换流程如下图,可结合代码查看。
注意项:需判断当前组元素数量是否小于k(在judgeGroupLen()中),小於则直接结束。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return null;
ListNode p,r=null,pre=null,gpre=null,gnext=null,first;
p=head;
first = head;
if(!judgeGroupLen(first,k)){
return head;
}
int i=0;
boolean flag = false; //flag表示p不是第一个该组节点
while(p!=null){
if((i<k-1)){
r = p.next;
if(flag){
p.next = pre;
}else{
flag = true;
}
pre = p;
p = r;
i++;
}else{
gnext = p.next;
p.next = pre;
//第一组,则gpre==null,取第一组的最后一个元素为最终返回的头节点
if(gpre!=null){
gpre.next = p;
}else{
head = p;
}
first.next = gnext;
//为下一组数据做初始化,并判断是否为最后一组
i=0;
gpre = first;
first = gnext;
if(!judgeGroupLen(first,k)){
return head;
}
pre = null;
p = first;
flag = false;
}
}
return head;
}
//判断是否是最后一组,且长度是否足够
public static boolean judgeGroupLen(ListNode m,int k){
int i=0;
while(i<k){
if(m == null){
return false;
}
m = m.next;
i++;
}
return true;
}
}