当前位置: 首页 > news >正文

【LeetCode】92. 反转链表 II

题目

【LeetCode】92. 反转链表 II

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

解题思路

核心要点:

  • 仅反转链表中从 leftright 的部分节点
  • 保持其他节点的相对位置不变
  • 需要正确处理反转部分与前后未反转部分的连接

下面介绍两种高效解法,均能在一次遍历中完成操作:

解法一:穿针引线法(逐个插入)

在需要反转的区间里,每遍历到一个节点,让这个新节点来到反转部分的起始位置。
在这里插入图片描述

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 创建虚拟头节点,简化头节点处理ListNode dummy = new ListNode(0);dummy.next = head;// p0 指向 left 节点的前一个节点ListNode p0 = dummy;for (int i = 1; i < left; i++) {p0 = p0.next;}// curr 是 left 位置的节点ListNode curr = p0.next;ListNode next;  // 保存 curr 的下一个节点// 从 left 到 right 需要反转 right-left 次for (int i = left; i < right; i++) {next = curr.next;  // 保存下一个节点// 步骤1:curr 跳过 next,直接指向 next 的下一个节点curr.next = next.next;// 步骤2:next 节点插入到 p0 的后面(成为反转部分的新头)next.next = p0.next;// 步骤3:p0 指向 next,完成插入p0.next = next;}return dummy.next;}
}

解法二:标准反转法(三指针)

这种方法先定位到反转范围,然后用标准的三指针反转法完成局部反转,最后重新连接链表。

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 创建哨兵节点ListNode sentinel = new ListNode(0, head);// p0 指向 left 节点的前一个节点ListNode p0 = sentinel;for (int i = 0; i < left - 1; i++) {p0 = p0.next;}// 初始化反转指针ListNode pre = null;ListNode cur = p0.next;  // cur 指向 left 节点// 反转 left 到 right 的节点(共 right-left+1 个节点)for (int i = 0; i < right - left + 1; i++) {ListNode nxt = cur.next;  // 保存下一个节点cur.next = pre;           // 反转指针pre = cur;                // pre 前移cur = nxt;                // cur 前移}// 连接反转后的链表p0.next.next = cur;  // 原 left 节点(现在是反转尾)连接到 right+1 节点p0.next = pre;       // p0 连接到反转后的新头(原 right 节点)return sentinel.next;}
}

解法二详解

同样以 head = [1,2,3,4,5], left=2, right=4 为例:

  1. 定位p0p0 移动到节点1(left前一个节点)
  2. 初始化指针pre=nullcur=2(left节点)
  3. 反转过程(循环3次)
    • 第1次:2→null,pre=2cur=3
    • 第2次:3→2,pre=3cur=4
    • 第3次:4→3,pre=4cur=5
    • 反转后局部:4→3→2
  4. 重新连接
    • p0.next.next = cur → 2→5(反转尾连接到right+1节点)
    • p0.next = pre → 1→4(p0连接到反转新头)
    • 结果:1→4→3→2→5(完成反转)

这种方法先完整反转局部链表,再进行连接,逻辑更符合常规的链表反转思路。

复杂度分析

两种方法的复杂度相同:

  • 时间复杂度:O(n),只需一次遍历链表
  • 空间复杂度:O(1),仅使用常数个额外指针

关键要点

  • 虚拟头节点(哨兵节点)是处理链表头节点可能被反转的有效技巧
  • 定位 left 前的节点(p0)是连接反转部分的关键
  • 两种方法都只需一次遍历,在遍历过程中判断并处理 leftright 范围的节点
  • 反转后必须正确连接三部分:p0 之前的部分、反转部分、right 之后的部分
http://www.dtcms.com/a/441879.html

相关文章:

  • LeetCode:90.最长有效括号
  • AI 重塑行业格局:从金融风控到智能制造的深度实践
  • 网站开发公共文件太仓营销型网站建设
  • MSM多标量乘法:策略及挑战
  • 做58一样的网站网站如何在国外推广
  • Vue渲染—深入VNode(h函数、JSX、render函数)
  • GPT_Data_Processing_Tutorial
  • 华为AC+AP无线网络组网与配置指南
  • 交互动效设计
  • 电子商务网站建设与管理相关文献邢台路桥建设总公司没有网站吗
  • Leetcode 3700. Number of ZigZag Arrays II
  • Turbopack介绍(由Vercel开发的基于Rust的高性能前端构建工具,用于挑战传统构建工具Webpack、vite地位)Next.js推荐构建工具
  • 网站自适应 如何做ui设计可以从事什么工作
  • 【学习记录】宝塔面板 + Docker 快速部署 RustDesk 自建远程控制服务器
  • 【3DGS复现】Autodl服务器复现3DGS《简单快速》《一次成功》《新手练习复现必备》
  • ollama的下载以及Spring AI Alibaba的ChatModel和ChatClient的流式输出和在idea的实现
  • 自己搭建服务器 发布网站 域名如何申请深圳专业做网站专业
  • 【pytest】fixture 内省(Introspection)测试上下文
  • 【开题答辩实录分享】以《基于python的奶茶店分布数据分析与可视化》为例进行答辩实录分享
  • 嵌入式硬件——基于IMX6ULL的I2C实现
  • 【ROS2学习笔记】分布式通信
  • 唐尧文化 网站建设工作总结邢台手机网站制作
  • 心脏病监测数据可视化分析
  • 【机器人】WMNav 将VLM融入世界模型 | 零样本目标导航 | IROS‘25
  • 第七课(零基础友好版)|机器学习像养宠物:数据—训练—测试(五年级·自学)
  • 无法解析插件 org.apache.maven.plugins:maven-site-plugin:3.12.1
  • 即墨网站建设哪里有安卓app怎么开发
  • 告别性能焦虑:Python 性能革命实践指南
  • Android dmabuf_dump 命令详解
  • Android 中的 mk 和 bp 文件编译说明