给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路:k个一组,即反转[1,k][k+1,2k]...,写一个反转[m,n]的方法,再循环即可
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
//------------------------------------------------------------------------------
//example:
// x -> x -> x -> x 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 x -> x -> x ->
// ^prevHead ^prev ^curr
// ^reverseHead ^reverseTail
//------------------------------------------------------------------------------
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode curr = head;
int length = 0;
while(curr!=null)
{
curr=curr.next;
length++;
}
ListNode res = head;
for(int n=0;n<length/k;n++){
res = reverseBetween(res,n*k+1,(n+1)*k);
}
return res;
}
private ListNode reverseBetween(ListNode head, int m, int n) {//翻转[m,n]位
if(m==n)
return head;
ListNode sentinel = new ListNode(0);
sentinel.next = head;
ListNode reverseHead = head;
ListNode reverseTail = head;
ListNode prevHead = sentinel;
for(int i=0;i<m-1;i++)
{
reverseHead = reverseHead.next;
prevHead = prevHead.next;
}
ListNode prev = reverseHead;
ListNode curr = prev.next;
for(int i=0;i<n-m;i++)
{
reverseTail = curr;
curr = curr.next;
reverseTail.next = prev;
prev = reverseTail;
}
prevHead.next = reverseTail;
reverseHead.next = curr;
return sentinel.next;
}
}