[路飞]k个一组翻转链表

128 阅读2分钟

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;
}