k个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
示例 3:
输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]
示例 4:
输入:head = [1], k = 1
输出:[1]
解析:
该提是基于前两个链表反转的基础上,1.先判断该链表是否支持翻转,定义变量p和q,判断两者是否相等,如果相等说明不能翻转,2.链表翻转跟前两个链表翻转一样,代码如下:
var reverseKGroup = function(head, k) {
//定义一个虚拟头
let ret = new ListNode(0,head);
//判断是否是有效链表
if(!ret || !ret.next || k < 2) return head;
//将新链表赋值给p,
let p = ret;
//其实新节点的下一个节点
let q = p.next;
//reverseN(q,k)该操作是判断改链表是否存在, 此时q = p.next 就相当于q是未翻转的头结点,
//p.next = reverseN(q,k) 此时p就是反转后的链表
while((p.next = reverseN(q,k)) != q){
//将未翻转部分赋值给p进行翻转
p = q;
//让q等于未翻转的头结点
q = p.next;
}
return ret.next;
};
//判断是否能翻转
var reverseN = function(head,n){
if(!head || !head.next || n < 2) return head;
let p = head,cnt = n;
//循环n次判断p是否存在,存在就支持翻转,不存在就返回head
while(--n && p) p = p.next;
// p不存在不支持翻转返回原节点
if(!p) return head;
//p存在支持翻转,通过_revverseN进行翻转
return _revverseN(head,cnt)
}
var _revverseN = function(head,n){
//判断是否需要反转
if(!head || !head.next || n < 2) return head;
//tail记录反转的头结点,p等到是的链表的最后一个节点,也就是待反转节点
let tail = head.next,p = _revverseN(head.next,n-1);
//将待反转节点指向空完成反转,此时head等于待反转节点
head.next = tail.next;
//将反转节点指向待反转节点
tail.next = head;
return p;
}