【刷题】牛客— NC21 链表内指定区间反转

在这里插入图片描述

链表内指定区间反转

  • 题目描述
  • 思路一(暴力破解版)
  • 思路二(技巧反转版)
  • 思路三(递归魔法版)
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

题目描述

在这里插入图片描述
根据题目描述,大致思路比较顺畅,需要使用链表的插入,创建等内容。

思路一(暴力破解版)

  1. 首先找到第 m-1 个节点并记录
  2. 然后开始反转
  3. 遍历 m - n 链表节点 ,并依次头插到一个新链表中
  4. m-1节点 指向新链表 ,新链表尾指向 n+1 个节点
  5. 完成反转。
typedef struct ListNode node;struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {//如果 m == n 不需要反转if (m == n ) return head;// 定义新链表的头尾node* new = NULL , *tail = NULL;//定义 cur 来指向当前节点 方便遍历node* cur = head;// 定义m-1节点  n+1节点node* mnode = NULL,*nnode = NULL;//开始遍历int count = 1;while(count < m){//记录第 m-1 节点if(count == m-1){mnode = cur;}cur = cur->next;count++;}//开始反转while(count <= n){//记录第 n+1个节点if(count == n){nnode = cur->next;}//每次创建新节点 拷贝node* newnode = (node*)malloc(sizeof(node));newnode->val = cur->val;//进行头插  new 为空则直接指向新节点 if(new == NULL){new = tail = newnode;}else{newnode->next = new;new = newnode;}//迭代cur = cur->next;count++;}// 分情况讨论// 如果 mnode == NULL 则标明 从头开始反转//直接将head = newif (mnode == NULL) {head = new;}//反之将 新链表插入在mnode后else mnode->next = new;// 新链表 指向nnodetail->next = nnode;return head;
}

运行效果:
在这里插入图片描述

思路二(技巧反转版)

该版本使用了一个十分巧妙的算法,不用额外开辟空间就能完成链表的反转。
在这里插入图片描述
通过从 m 到 n - 1的遍历
逐个将 temp 移到 prev 的后面
完成局部头插。

typedef struct ListNode node;
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {//定义一个 头结点 ,方便操作node* H = (node*)malloc(sizeof(node));H->next = head;//两个指针 分别指向 当前节点 和 前节点node* prev = H,*cur = head;// 遍历到 第m-1个节点for(int i = 1;i < m; i++){prev = cur;cur = cur->next;}//开始反转for(int i = m; i<n;i++){// temp 指向 cur后一个节点node* temp = cur->next;// 将temp移动到 prev 后// cur 移动到 temp 位置cur->next = temp->next;temp->next = prev->next;prev->next = temp;}//返回return H->next;
}

运行效果:
在这里插入图片描述

思路三(递归魔法版)

思路来自牛客官方
我们来看看另一种分析:如果m == 1,就相当于反转链表的前 n 元素;如果 m != 1,我们把 head 的索引视为 1,那么我们是想从第 m 个元素开始反转,如果把 head.next 的索引视为1,那相对于 head.next的反转的区间应该是从第 m−1 个元素开始的,以此类推,反转区间的起点往后就是一个子问题,我们可以使用递归处理:

终止条件: 当m == 1,就可以直接反转前n个元素。
返回值: 将已经反转后的子问题头节点返回给上一级。
本级任务: 递归地缩短区间,拼接本级节点与子问题已经反转的部分。

从头开始往后去掉前面不反转的部分

ListNode node = reverseBetween(head.next, m - 1, n - 1)

而每次反转,如果 n == 1,相当于只颠倒第一个节点,如果不是,则进入后续节点(子问题),因此反转过程也可以使用递归:

终止条件: 当n == 1时,只反转当前头节点即可。
返回值: 将子问题反转后的节点头返回。
本级任务: 缩短 n 进入子问题反转,等子问题回到本级再反转当前节点与后续节点的连接。

颠倒后续的节点,直到n=1为最后一个

ListNode node = reverse(head.next, n - 1)

具体做法:

  1. 准备全局变量temp,最初等于null,找到递归到第n个节点时,指向其后一个位置,要将反转部分的起点(即反转后的尾)连接到这个指针。
  2. 按照第一个递归的思路缩短子问题找到反转区间的起点,将反转后的部分拼接到前面正常的后面。
  3. 按照第二个递归的思路缩短终点的子问题,从第n个位置开始反转,反转过程中每个子问题作为反转后的尾,都要指向temp。
 typedef struct ListNode ListNode;ListNode* temp = NULL;ListNode* reverse(ListNode* head, int n){//只颠倒第一个节点,后续不管if(n == 1){temp = head->next;return head;}//进入子问题ListNode* node = reverse(head->next, n - 1);//反转head->next->next = head;//每个子问题反转后的尾拼接第n个位置后的节点head->next = temp;return node;
}
ListNode* reverseBetween(ListNode* head, int m, int n) {//从第一个节点开始if(m == 1)return reverse(head, n);//缩减子问题ListNode* node = reverseBetween(head->next, m - 1, n - 1);//拼接已翻转head->next = node;return head;
}

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

LV.23 D2 开发环境搭建及平台介绍 学习笔记

一、Keil MDK-ARM简介及安装 Keil MDK&#xff0c;也称MDK-ARM&#xff0c;Realview MDK &#xff08;Microcontroller Development Kit&#xff09;等。目前Keil MDK 由三家国内代理商提供技术支持和相关服务。 MDK-ARM软件为基于Cortex-M、Cortex-R4、ARM7、ARM9处理器设备…

ESP8266 常用AT指令

一、ESP8266的AT指令要点、常见错误 AT指令要大写;以"\r\n"作结尾;串口通信&#xff0c;115200-None-8-1;支持2.4G频段&#xff0c;不支持5G频段 &#xff08;如果用手机创建热点&#xff0c;注意选择2.4G&#xff09;不支持中文的wifi名称工作模式&#xff0c;上电…

选择排序和快速排序(1)

目录 选择排序 基本思想 选择排序的实现 图片实现 代码实现 快速排序 基本思想 快速排序的实现 图片实现 代码实现 选择排序 基本思想 每一次从待排序的数据元素中选出最小&#xff08;最大&#xff09;的元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部…

网络原理-TCP/IP(7)

目录 网络层 路由选择 数据链路层 认识以太网 以太网帧格式 认识MAC地址 对比理解MAC地址和IP地址 认识MTU ARP协议 ARP协议的作用 ARP协议工作流程 重要应用层协议DNS(Domain Name System) DNS背景 NAT技术 NAT IP转换过程 NAPT NAT技术的优缺点 网络层 路由…

《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)

文章目录 4.1 接口的定义与实现 - Go 语言的多面手4.1.1 基础知识讲解4.1.2 重点案例&#xff1a;动物乐队功能描述实现代码 4.1.3 拓展案例 1&#xff1a;通用支付系统拓展案例 1&#xff1a;通用支付系统功能描述实现代码 4.1.4 拓展案例 2&#xff1a;动物园管理器拓展案例 …

旅游出门千万别忘带这些!花的不多,享受翻倍!随身wifi看这篇,高性价比高口碑随身wifi推荐

春节长假&#xff0c;大家都去哪儿玩了呢&#xff1f;我反正带着我的小背包&#xff0c;走遍了祖国的大好河山&#xff01; 得益于之前几次长假出行的经验&#xff0c;这次出行体验十分完美。除了详细完备的出行攻略&#xff0c;还有就是一些出行好物&#xff0c;虽然不起眼&am…

QShortcut

一、QShortcut简介 QShortcut是Qt框架中提供的一个类&#xff0c;用于创建和管理键盘快捷键。它允许开发者为应用程序定义一组快捷键组合&#xff0c;当用户按下这些组合键时&#xff0c;可以触发相应的动作或事件。QShortcut的使用使得用户能够更加方便、快捷地操作应用程序&…

【python】python入门(变量名)

Hi~ o(*&#xffe3;▽&#xffe3;*)ブ今天一起来看看python入门之变量名吧~~ 变量名的规定&#xff1a; 举个例子&#xff1a; “违法”的变量名们 my love/my &#xff01;love错误&#xff1a;中间不能是空格或者其他符号1my_love错误&#xff1a;不能数字开头"my_l…

shell编程:求稀疏数组中元素的和(下标不连续)

#!/bin/basharr([2]3 [5]2 [6]2 [9]1)for i in "${!arr[]}" dosum$((sumarr[i])) doneecho $sumBash 脚本中&#xff0c;* 和 符号在数组上下文中有不同的用途。当使用它们来遍历数组时&#xff0c;必须了解它们之间的区别。 * (无前置感叹号 !)&#xff1a; 在索引…

用HTML、CSS和JS打造绚丽的雪花飘落效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetGBK"><style>* {margin: 0;padding: 0;}#box {width: 100vw;heig…

Swift Combine 使用 ObservableObject 与 SwiftUI 模型作为发布源 从入门到精通二十

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

C语言系列(所需基础:大学C语言及格)-1-编译器/简单的求和代码/数据类型/变量的分类/变量的作用域和生命周期

文章目录 一、编译器&#xff08;使用在线编译器&#xff09;二、简单的求和代码三、数据类型四、变量的分类五、变量的作用域和生命周期 一、编译器&#xff08;使用在线编译器&#xff09; 为了方便&#xff0c;我使用的是在线的C语言编译器进行程序的运行。 链接&#xff1…

Springboot整合第三方技术-任务(Quartz、Task)

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

MVC 、DDD、中台、Java SPI(Service Provider Interface)

文章目录 引言I 单体架构DDD实现版本1.1 核心概念1.2 DDD四层架构规范1.3 案例1.4 请求转发流程II 领域服务调用2.1 菱形对称架构2.2 中台III Java SPI3.1 概念3.2 实现原理see alsojava -cp引言 典型的MVC版本实现方式: <

HTTP协议-响应报文详解(Respond)

目录 前言&#xff1a; 1.Respond报文 1.1报文格式 1.2格式图解 2.状态行&#xff08;首行&#xff09; 2.1状态码/状态码解释 &#xff08;1&#xff09;200 OK &#xff08;2&#xff09;404 Not Found &#xff08;3&#xff09;403 Forbidden &#xff08;4&#…

书生浦语大模型实战营-课程笔记(4)

微调分为两种&#xff0c;增量预训练和指令跟随。 指令跟随微调&#xff1a; 1.只对答案计算Loss 2.训练时数据为一问一答的形式&#xff08;input和output&#xff09; 增量预训练&#xff1a; 只需要output的数据进行训练 xtuner:微调框架 操作部分的笔记参考git上的文档…

模块、包、库的区别

这三者都是通过import和from…import…语句实现的。 模块&#xff08;module&#xff09; Python 模块(Module)&#xff0c;是一个 Python 文件&#xff0c;以 .py 结尾&#xff0c;包含了 Python 对象定义和Python语句。 简单来说任何一个以.py的文件都可以视为是一个模块(…

人工智能学习与实训笔记(六):神经网络之智能推荐系统

人工智能专栏文章汇总&#xff1a;人工智能学习专栏文章汇总-CSDN博客 本篇目录 七、智能推荐系统处理 7.1 常用的推荐系统算法 7.2 如何实现推荐 7.3 基于飞桨实现的电影推荐模型 7.3.1 电影数据类型 7.3.2 数据处理 7.3.4 数据读取器 7.3.4 网络构建 7.3.4.1用户特…

家庭动态网络怎么在公网访问主机数据?--DDNS配置(动态域名解析配置)

前言 Dynamic DNS是一个DNS服务。当您的设备IP地址被互联网服务提供商动态变更时,它提供选项来自动变更一个或多个DNS记录的IP地址。 此服务在技术术语上也被称作DDNS或是Dyn DNS 如果您没有一个静态IP,那么每次您重新连接到互联网是IP都会改变。为了避免每次IP变化时手动更…

使用C++,实现高精度加减乘除法运算!

我的个人主页 {\large \mathsf{{\color{Red} 我的个人主页} } } 我的个人主页 我的专栏&#xff1a; \mathcal{{\color{Green} 我的专栏&#xff1a;} } 我的专栏&#xff1a; 《精选文章》《算法》《每日一道编程题》《高精度算法》 文章目录 前言高精度计算初始模版string 转…