[路飞]-K个一组翻转链表

530 阅读2分钟

我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

  1. 首先将给定的链表进行分组,每K个一组
  2. 将每组内部的链表进行翻转
  3. 节点个数小于K翻转结束后,再重新连接,

image.png

开始解题
  1. 需要给链表创建一个临时节点fake指向head,定义两个变量pre,tail都在指向临时节点fake,定义nexttail的后面,tail根据K向后移动,然后进行翻转。翻转结束,将pre``next连接。
  2. 完成1后,将pre head tail next向后移动K的位置,进行翻转。将pre next连接
  3. 重复2步骤,直到tail.next不存在
function myReverse(head, tail) {
  let prev = tail.next;
  let cur = head;
  while (prev != tail) {
    const next = cur.next;
    cur.next = prev;
    prev = cur;
    cur = next;
  }
  // 返回新头 新尾
  return [tail, head];
}
var reverseKGroup = function (head, k) {
  // 虚拟头节点
  let fake = {
      next: head
  }
 
  let pre = fake; // 定义pre
  while (head) {
    let tail = pre;
    for (let i = 0; i < k; i++) {
      // 将tail向后移动K次
      tail = tail.next;
      // 如果不存在跳出
      if (!tail) {
        return fake.next;
      }
    }
    const next = tail.next;
    [head, tail] = myReverse(head, tail);
    // 确认下一个分组的头

    // 连接头尾
    pre.next = head;
    tail.next = next;

    // 确定下一分组的头尾
    head = tail.next;
    pre = tail;
  }
  return fake.next;
};

至此K个一组翻转链表就完成了,所运用到的翻转函数还是之前的对整个链表进行翻转,其次就是pre next的记录,翻转过后会使用pre next拼接,如果tail.next存在继续进行下一分组的翻转,否则结束,返回hair.next

总结

算法需要的是一种思维模式,当我们所需要的思维达到了一定的层次时,也就是说我们见过了足够多的算法题,看见题目就能想到对应的思路,这个时候就能从容应对了。所以在最初的我们遇到算法是最难的时候,只要一个个坚持去突破,相信会有手撕它的一天。

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~