Leetcode 刷题 25. K 个一组翻转链表

很多前端的同学对数据结构和算法这块没有太多的概念,很多leetcode的题目看不懂,有时候可能看了题解也不知道是什么意思。上一篇我们对链表的数据结构有了了解,下面根据题目来练习一下

25. K 个一组翻转链表

题目

给你链表的头节点 head ,每 k个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

题解

我们首先来看下这道题想要干什么的。K个一组翻转链表。比如示例2,k为3那么就是3个节点一组翻转,那么最终的效果为前三个节点翻转,还剩两个节点不足3个,则不翻转,直接返回。

reverse 实现一个单纯的翻转函数

我们首先来实现一个reverse的函数,第一个参数为head(需要翻转的起始点),第二个参数为n(需要翻转的个数)这个函数用来翻转一组链表,如果k为3,那么这个函数就只翻转3个节点,如果不满足3个,则直接返回原有的结构。

如果k为3,那么根据上图起始点传入的是1的时候,是正常可以翻转的,则需要返回翻转后的链表;如果起始点传入的是4的时候,是不可以翻转的,则直接返回之前的结构。

下面看下代码是如何实现的

js 复制代码
var reverse = function (head, n) {
  let pre = head, cur = head, con = n;
  while (--n && pre) {
    pre = pre.next
  }

  if (!pre) return head;
  pre = null
  while (con--) {
    [cur.next, pre, cur] = [pre, cur, cur.next]
  }

  head.next = cur
  return pre
}

前7行代码主要是为来判断链表的长度够不够翻转。如果n为3,那么通过while循环,只会循环2次,如果两次循环之后,pre还存在,就可以说明可以完整的翻转一组。如果不存在了,说明这一组不够翻转的,则直接返回头节点即可。

如果够翻转的,那么将pre直接赋值为null,作为虚拟头节点。这里对翻转操作不太了解的可以看下前两篇文章Leetcode 刷题 206. 反转链表,Leetcode 刷题 92. 反转链表 II

循环翻转

我们先看下代码

js 复制代码
var reverseKGroup = function (head, k) {
  if (!head) return null
  let ret = new ListNode(null, head), pre = ret;
  do {
    pre.next = reverse(pre.next, k)
    for (let i = 0; i < k && pre; i++) {
      pre = pre.next
    }
    if (!pre) break;
  } while (1)

  return ret.next
};

首先定义一个虚拟头节点ret, 将ret赋值给pre。通过循环,每次将pre.next的节点传给reverse。这里我们用图来表示一下

此时pre还处在虚拟头的位置,而且第一次循环已经翻转了一组,然后通过for循环将pre移动到下一次翻转的起点。

当第二次循环翻转的时候,reverse函数中判定不够翻转的,直接就返回原来的结构了。然后再执行for循环的时候,当i为2时候,由于prenull了,for循环结束,同时do while循环退出,最后直接返回ret.next即可

完整代码

js 复制代码
var reverseKGroup = function (head, k) {
  if (!head) return null
  let ret = new ListNode(null, head), pre = ret;
  do {
    pre.next = reverse(pre.next, k)
    for (let i = 0; i < k && pre; i++) {
      pre = pre.next
    }
    if (!pre) break;
  } while (1)

  return ret.next
};

var reverse = function (head, n) {
  let pre = head, cur = head, con = n;
  while (--n && pre) {
    pre = pre.next
  }

  if (!pre) return head;
  pre = null
  while (con--) {
    [cur.next, pre, cur] = [pre, cur, cur.next]
  }

  head.next = cur
  return pre
}

欢迎大家点赞评论,大家一起学习一起进步!!!

相关推荐
Highcharts.js7 分钟前
抉择之巅:从2029年回望2026年——企业可视化“战略分水岭”?
前端·javascript·信息可视化·编辑器·echarts·highcharts
沙振宇7 分钟前
【Web】使用Vue3+PlayCanvas开发3D游戏(十)让人物动起来
前端·游戏·3d·人物·
军军君0137 分钟前
数字孪生监控大屏实战模板:空气污染监控
前端·javascript·vue.js·typescript·前端框架·echarts·数字孪生
m0_6948455737 分钟前
opendataloader-pdf部署教程:构建PDF数据处理系统
服务器·前端·前端框架·pdf·开源
小李子呢021143 分钟前
前端八股浏览器网络(1)---响应头
前端
倚栏听风雨1 小时前
详细讲解下 for...of vs for await...of 区别
前端
REDcker1 小时前
Safari 26.4 新增 WebTransport:对 iOS WebView 的影响与落地建议
前端·ios·safari
练习前端两年半1 小时前
Vue3 KeepAlive 深度揭秘:组件缓存的魔法是如何实现的?
前端·vue.js·面试
音视频牛哥1 小时前
鸿蒙 NEXT RTSP/RTMP 播放器如何回调 RGB 数据并实现 AI 视觉算法分析
人工智能·算法·harmonyos·鸿蒙rtmp播放器·鸿蒙rtsp播放器·鸿蒙next rtsp播放器·鸿蒙next rtmp播放器
飞Link1 小时前
掌控 Agent 的时空法则:LangGraph Checkpoint (检查点) 机制深度实战
开发语言·python·算法