给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
题解
递归
题解转载自leetcode
大致过程可以分解为
1、找到待翻转的k个节点(注意:若剩余数量小于 k 的话,则不需要反转,因此直接返回待翻转部分的头结点即可)。
2、对其进行翻转。并返回翻转后的头结点(注意:翻转为左闭又开区间,所以本轮操作的尾结点其实就是下一轮操作的头结点)。
3、对下一轮 k 个节点也进行翻转操作。
4、将上一轮翻转后的尾结点指向下一轮翻转后的头节点,即将每一轮翻转的k的节点连接起来。
class Solution {
ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return null;
//区间[a,b)有k个待反转元素
ListNode a=head,b=head;
for(int i=0;i<k;i++){
//不足k个,不需要反转,base case
if(b==null) return head;
b=b.next;
}
//反转前k个元素
ListNode newHead = reverse(a,b);
//递归反转后续元素并连接起来
//反转后b是头,a是尾,a后接后半截链表
a.next=reverseKGroup(b,k);
return newHead;
}
/** 反转区间 [a, b) 的元素,注意是左闭右开 */
ListNode reverse(ListNode a, ListNode b) {
ListNode pre=null,cur=a,nxt=a;
//相对于反转整个链表,将while循环的条件由cur!=null,改为cur!=b
while(cur!=b){
nxt=cur.next;
cur.next=pre;
pre=cur;
cur=nxt;
}
return pre;
}
}