给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
难度是困难题,不过思路好想,就是实现的时候容易写错。
我的思路:1.首先是链表翻转问题,在每组内都找一个头结点(第一组new一个结点作为头结点,其他组的头结点就是前面一组的原来链表的第一个结点)用头插法进行该组的翻转。2.其次是分组问题,每k个进行翻转,不足k个不动。那么每次新到一组,首先把头结点的next结点(该组第一个结点)作为下一组的头结点。每组第一个结点是不需要动的,所以直接从第二个结点开始头插。
3.因为我是从每组第二个开始头插的,然后也根据实际题目情况,当k等于时候直接返回原链表即可,避免了bug。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public ListNode reverseKGroup(ListNode head, int k) {
if(k == 1)
return head;
ListNode lengthNode = head;
int listLength = 0;
while (lengthNode != null){
lengthNode = lengthNode.next;
listLength++;
}
ListNode pre = new ListNode(-1);//pre为当前组的头结点
pre.next = head;
ListNode nextPre = pre.next;//下一组的头结点(原链表中每组的第一个结点)
int index = 0;
boolean flag = false;//用来记录找到最终链表的起始结点
while (listLength >= k){
while (index < k){//每组的翻转
if(index == 0){//每组第一个结点不需要动
index++;
nextPre = head;
head = head.next;
continue;
}
if(index == k-1 && !flag){//找到最终链表的起始结点
lengthNode = head;
flag = true;
}
ListNode tmpNode = head.next;
head.next = pre.next;
pre.next = head;
nextPre.next = tmpNode;
head = nextPre.next;
index++;
}
pre = nextPre;
nextPre = pre.next;
index = 0;
listLength = listLength - k;
}
return lengthNode;
}