题目描述
给定一个链表,一次反转链表 k 的节点并返回其修改后的列表。
如果节点的数量不是k的倍数,那么最后遗漏的节点应该保持原样。
不能更改节点中的值,只能更改节点本身。
只允许使用常量内存。
样例1
输入:
list = 1->2->3->4->5->null
k = 2
输出:
2->1->4->3->5
样例2
输入:
list = 1->2->3->4->5->null
k = 3
输出:
3->2->1->4->5
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param head: a ListNode
* @param k: An integer
* @return: a ListNode
*/
public ListNode reverseKGroup(ListNode head, int k) {
if(k<=1) //不用反转的情况
return head;
ListNode Pointer=head; //第n*k个节点,反转节点的第一个节点,用于连接未进行反转部分的链表,是每次反转后部分链表的尾节点
ListNode newHead=head; //反转后的头节点
for(int j=0;j<k-1;j++){
newHead=newHead.next;
if (newHead==null) { //从头节点开始第k个为新的头节点
if(j==k-1) //如果链表刚好有k个节点,跳出循环前往反转
break;
else
return head; //否则,k大于链表长度,不能进行反转,返回
}
}
while(Pointer.next!=null)
{
ListNode Prev=Pointer; //记录前地址
ListNode Curr=Pointer.next; //记录现地址
int counter=1; //计算有没有达到k次
while (Curr!=null&&counter<k) { //用三个指针进行两个节点间的反转
ListNode Next=Curr.next;
Curr.next=Prev;
Prev=Curr;
Curr=Next;
counter++; //进行k次后Pointer会与前一节点形成循环链表
}
ListNode Counter=Curr;
if(Curr==null){ //如果刚好整个链表长度可以被k整除
Pointer.next=null;
return newHead;
}
for (int i = 1; i < k; i++) {//验证链表后还有无k个节点可以反转
if(Counter.next==null){ //没有则Pointer链接上未进行反转的第一个节点并返回
Pointer.next=Curr;
return newHead;
}
Counter=Counter.next;
}
Pointer.next=Counter; //Counter为下k个节点进行反转后的头节点
Pointer=Curr; //Pointer指向未进行反转链表的第一个节点
}
return newHead;
}
}
结果:
Accepted
199 ms时间消耗·14.94 MB空间消耗