【链表】Leetcode 92. 反转链表 II【中等】

反转链表 II

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

示例 1:
在这里插入图片描述
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

解题思路1

1、遍历链表:

  • 找到 left 前面的节点(preLeft),以及 left 节点本身(leftNode)。
  • 找到 right 节点(rightNode),以及 right 后面的节点(postRight)。
    2、反转部分链表:
  • 将 leftNode 到 rightNode 之间的节点进行反转。
    3、重新连接:
  • 将 preLeft 的 next 指向 rightNode。
  • 将 leftNode 的 next 指向 postRight。

java实现1

public class ReverseBetween {public static class ListNode {int val;ListNode next;ListNode(int x) {val = x;}}public ListNode reverseBetween(ListNode head, int left, int right) {// 创建虚拟头节点,简化边界处理ListNode dummyNode = new ListNode(-1);dummyNode.next = head;ListNode preLeft = dummyNode;// 第 1 步:找到 left 节点的前一个节点 prefor (int i = 0; i < left - 1; i++) {preLeft = preLeft.next;}// 第 2 步:找到 right 节点ListNode rightNode = preLeft;for (int i = 0; i < right - left + 1; i++) {rightNode = rightNode.next;}// 第 3 步:切断出一个子链表(截取链表)ListNode leftNode = preLeft.next;ListNode postRight = rightNode.next;// 切断链接preLeft.next = null;rightNode.next = null;// 第 4 步:反转链表的子区间reverseLinkedList(leftNode);// 第 5 步:接回到原来的链表中preLeft.next = rightNode;leftNode.next = postRight;return dummyNode.next;}private void reverseLinkedList(ListNode head) {ListNode pre = null;ListNode cur = head;while (cur != null) {ListNode next = cur.next;cur.next = pre;pre = cur;cur = next;}}public static void main(String[] args) {ReverseBetween reverseBetween = new ReverseBetween();// 创建示例链表 1->2->3->4->5ListNode head = new ListNode(1);head.next = new ListNode(2);head.next.next = new ListNode(3);head.next.next.next = new ListNode(4);head.next.next.next.next = new ListNode(5);// 测试反转第2到第4个节点ListNode newHead = reverseBetween.reverseBetween(head, 2, 4);printList(newHead); // 输出: 1->4->3->2->5}// 辅助方法:打印链表public static void printList(ListNode head) {ListNode current = head;while (current != null) {System.out.print(current.val);if (current.next != null) {System.out.print("->");}current = current.next;}System.out.println();}
}

时间空间复杂度1

  • 时间复杂度:O(N),其中 N是链表总节点数。最坏情况下,需要遍历整个链表。

  • 空间复杂度:O(1)。只使用到常数个变量。

解题思路2

解题思路1缺点是:如果 left 和 right 的区域很大,恰好是链表的头节点和尾节点时,找到 left 和 right 需要遍历一次,反转它们之间的链表还需要遍历一次,虽然总的时间复杂度为 O(N),但遍历了链表 2 次。

1、初始化和定位:

  • 使用指针 pre 遍历到 left 前一个节点,定位到反转区间的前一个节点。
    局部反转:

2、使用三个指针 pre、cur 和 next 进行反转操作:

  • pre 指向反转区间的前一个节点。

  • cur 指向当前需要反转的节点。

  • next 指向当前节点的下一个节点,用于在反转过程中进行位置交换。
    3、反转区间:

  • 通过逐个移动 cur 和 next 节点的位置,在反转区间内执行交换操作,完成局部反转。

图解:
在这里插入图片描述

在这里插入图片描述
核心代码分析:

  • curr:指向待反转区域的第一个节点 left;
  • next:永远指向 curr 的下一个节点,循环过程中,curr 变化以后 next 会变化;
  • pre:永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变。
   			// 先将 curr 的下一个节点记录为 next;next = cur.next;//执行操作1:把 curr 的下一个节点指向 next 的下一个节点cur.next = next.next;//执行操作2:把 next 的下一个节点指向 pre 的下一个节点next.next = pre.next;//执行操作3:把 pre 的下一个节点指向 nextpre.next = next;

在这里插入图片描述
在这里插入图片描述
后续同理
在这里插入图片描述
在这里插入图片描述

java实现2

public class ReverseBetween {public static class ListNode {int val;ListNode next;ListNode(int x) {val = x;}}public ListNode reverseBetween(ListNode head, int left, int right) {// 设置 dummyNode 是这一类问题的一般做法ListNode dummyNode = new ListNode(-1);dummyNode.next = head;ListNode pre = dummyNode;//找到pre结点for (int i = 0; i < left - 1; i++) {pre = pre.next;}//当前current节点ListNode cur = pre.next;ListNode next;for (int i = 0; i < right - left; i++) {// cur的下一个节点赋值给nextnext = cur.next;//cur指向next指向的节点cur.next = next.next;//next指向pre指向的节点next.next = pre.next;//pre指向nextpre.next = next;}return dummyNode.next;}public static void main(String[] args) {ReverseBetween reverseBetween = new ReverseBetween();// 创建示例链表 1->2->3->4->5ListNode head = new ListNode(1);head.next = new ListNode(2);head.next.next = new ListNode(3);head.next.next.next = new ListNode(4);head.next.next.next.next = new ListNode(5);// 测试反转第2到第4个节点ListNode newHead = reverseBetween.reverseBetween(head, 2, 4);printList(newHead); // 输出: 1->4->3->2->5}// 辅助方法:打印链表public static void printList(ListNode head) {ListNode current = head;while (current != null) {System.out.print(current.val);if (current.next != null) {System.out.print("->");}current = current.next;}System.out.println();}
}

时间空间复杂度2

  • 时间复杂度:O(N),其中 N 是链表总节点数。最多只遍历了链表一次,就完成了反转。

  • 空间复杂度:O(1)。只使用到常数个变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/332927.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang、laravel对接stripe海外支付接口的总结和流程(通俗易懂)

目录 stripe是什么&#xff1f; 环境 配置后台 首先让管理员把你设置成为开发者 然后进入后台 然后你要创建产品&#xff0c;开单周期要写每天&#xff0c;我这里理解成每天都会有人买的 获取产品id 获取密钥&#xff0c;后续代码需要用到 支付代码 唤起支付页面 测…

Jenkins pipeline发布前端项目

说明&#xff1a;第一次使用jenkins生成pipeline片段&#xff0c;做个记录... 1.全局工具配置添加自定义node版本 2.系统管理添加前端应用部署服务器 2.1 点击高级选择账号密码验证方式&#xff0c;添加服务器的用户和密码 3.系统管理--凭据--系统--全局凭据--添加自己的git凭据…

网站笔记:huggingface model memory calculator

Model Memory Utility - a Hugging Face Space by hf-accelerate 这个工具可以计算在 Hugging Face Hub上托管的大型模型训练和执行推理时所需的vRAM内存量。模型所需的最低推荐vRAM内存量表示为“最大层”的大小&#xff0c;模型的训练大约是其大小的4倍&#xff08;针对Adam…

PL5358A 单芯锂离子/聚合物电池保护IC芯片

一般说明 PL5358A系列产品是锂离子/聚合物电池保护的高集成解决方案。PL5358A包含先进 的功率MOSFET&#xff0c;高精度电压检测电路和延迟电路。5358A被放入一个超小的SOT23-5封装&#xff0c;只有一个外部元件&#xff0c;使其成为理想的解决方案&#xff0c;在有限的…

NDIS协议驱动(一)

Microsoft Windows 操作系统使用基于 1978 年国际标准化组织 (ISO) 开发的七层网络模型的网络体系结构。 ISO 开放系统互连 (OSI) 参考模型将网络描述为“一系列协议层&#xff0c;具有分配给每个层的一组特定函数。 每个层都向更高层提供特定的服务&#xff0c;同时阻止这些层…

中国区 AWS 控制台集成 ADFS 登录

前言 本文将使用一台 Windows Server 2019 服务器实现自建 AD ADFS 环境集成到中国区 AWS 控制台进行单点登录. 参考文档: https://aws.amazon.com/cn/blogs/china/adfs-bjs/ 配置 AD 生产环境建议先给本地连接设置静态 IP 地址, 不设置也没事儿, 后面配置功能的时候会有 W…

设计模式11——代理模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 代理模式&#xff08;Proxy&am…

git工作流程

以财务开发为例子&#xff1a; 1. 新建分支 1.1. upstream新建分支&#xff1a;finance-feature 1.2. origin新建对应分支&#xff1a;finance-feature 1.3 新建本地分支 git branch finance-feature 注&#xff1a; 同步远程分支&#xff1a;git fetch upstream feature…

【设计模式】JAVA Design Patterns——Command(事务模式)

&#x1f50d;目的 将请求封装为对象&#xff0c;从而使你可以将具有不同请求的客户端参数化&#xff0c;队列或记录请求&#xff0c;并且支持可撤销操作。 &#x1f50d;解释 真实世界例子 有一个巫师在地精上施放咒语。咒语在地精上一一执行。第一个咒语使地精缩小&#xff0…

群晖NAS安装web服务器和搭建PHP环境

文章目录 安装Web Station 和 PHP配置PHP配置新站点&#xff08;虚拟主机&#xff09;&#xff1a;配置nginx 安装MariaDB修改数据库配置配置远程连接远程连接 最近折腾了一台群晖NAS&#xff0c;并搭建了一套web服务器&#xff0c;关于其中的一些设置&#xff0c;和传统的Linu…

力扣HOT100 - 31. 下一个排列

解题思路&#xff1a; 数字是逐步增大的 步骤如下&#xff1a; class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…

基于51单片机多功能太阳能充电器设计

1 绪论1.1 本课题研究背景及现状 当代社会随着一些不可再生资源如煤炭&#xff0c;石油等日益减少&#xff0c;使得各国社会经济越来越受能源问题的约制&#xff0c;因此许多国家开始逐渐的实行“阳光计划”&#xff0c;开发洁净的能源如太阳能&#xff0c;用以成为本国经济发…

javaEE—图书管理系统(基础代码版)

前言&#xff1a; 本篇博客是集合了javaEE所学的知识构建的一个基础框架&#xff0c;讲述着面向对象的过程是如何做到多对象交互协作完成框架的构建的。利用了数组&#xff0c;接口&#xff0c;类和对象&#xff0c;抽象类&#xff0c;Object类等知识来完成。 后续会加入数据…

BGP选路实验

编写实验报告&#xff1a; 1、拓扑信息 2、要求及分析 3、配置命令 4、测试 1、拓扑信息 2、要求及分析 1、使用preval策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2、使用AS Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3、配置MED策略&#xff0c;确保R4…

嵌入式UI开发-lvgl+wsl2+vscode系列:1、资料收集以及Windows下WSL2模拟环境运行示例demo

文章目录 一、前言二、资料收集三、Windows下WSL2上编译运行lvgl的demo程序1、lvgl简介2、lvgl特性3、配置要求4、Windows下vscodewsl2模拟环境搭建4.1、安装vscodewsl24.2、下载获取项目&#xff1a;4.3、安装显卡驱动4.4、下载lvgl并编译运行示例demo 四、最后 一、前言 UI界…

leetcode437 路径总和III-哈希表+前缀和

题目 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始&#xff0c;也不需要在叶子节点结束&#xff0c;但是路径方向必须是向下的&#xff08;只能从父节点到子节…

专为汽车内容打造的智能剪辑解决方案

汽车内容创作已成为越来越多车主和汽车爱好者热衷的活动。然而&#xff0c;如何高效、便捷地将行车途中的精彩瞬间转化为高质量的视频作品&#xff0c;一直是困扰着广大用户的一大难题。美摄科技凭借其深厚的视频处理技术和智能分析能力&#xff0c;推出了专为汽车内容记录而生…

探索python循环逻辑的魅力:从无限到有限

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;循环逻辑的初步认识 二、无限循环&#xff1a;持续运转的引擎 三、有…

JavaWeb-JS

目录 学习重点 什么是 JavaScript? Web标准 JS的引入方式 JS的基本语法 JS的函数 JS的对象 JS事件监听 学习重点 js 引入方式 js 基础语法 js 函数 js 对象 js 事件监听 什么是 JavaScript? Web标准 Web 标准也称为网页标准 &#xff0c;由一系列的标准组成&#xff0…

安泰电子:功率放大器的选择方法有哪些

选择适合的功率放大器是实现电子系统中的关键步骤之一。以下是一些选择功率放大器的常用方法和考虑因素&#xff1a; 功率需求&#xff1a;首先确定你的系统需要多大的功率输出。功率输出需求通常由被驱动设备的功率要求决定。计算出所需功率后&#xff0c;选择一个具有适当功率…