【刷题】牛客— 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.hqwc.cn/news/473440.html

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

相关文章

typescrip接口 interface详解,以及ts实现多态

ts 接口 当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的 示例如下 当一个对象类型被多次使用时,可以看到,很明显代码有大量的冗余 let personTom: { name: string, age?: number, sayHi(name: string): void } {name: Tom,sayHi(n…

阿里云ECS香港服务器性能强大、cn2高速网络租用价格表

阿里云香港服务器中国香港数据中心网络线路类型BGP多线精品&#xff0c;中国电信CN2高速网络高质量、大规格BGP带宽&#xff0c;运营商精品公网直连中国内地&#xff0c;时延更低&#xff0c;优化海外回中国内地流量的公网线路&#xff0c;可以提高国际业务访问质量。阿里云服务…

ClickHouse--12-可视化工具操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 可视化工具操作1 tabixhttp://ui.tabix.io/ 2 DBeaverhttps://dbeaver.io/download/ 可视化工具操作 1 tabix tabix 支持通过浏览器直接连接 ClickHouse&#xff…

网页端、APP端页面国际化-多语言翻译与半自动比对程序

网站和APP国际化翻译过程中&#xff0c;对多语言配置文件的翻译与比对模板&#xff0c;记录工作经验。 最佳的模式是&#xff1a;前期尽量做好全部菜单按钮多语言TS配置文件&#xff0c;网页端、APP端和管理端使用同一个配置文件&#xff0c;比如buttons.ts,menus.ts&#xff…

C#,整数转为短字符串(Short string)的加解密算法与源代码

1 整数转为短字符串的应用 网站生成的动态 URL 往往以内容序列号id为标识与参数&#xff0c;比如&#xff1a; http://www.jerry.com/tom.aspx?id1 使用 Web Rewrite&#xff0c;可以实现网页静态化&#xff0c;称为&#xff1a; http://www.jerry.com/content/1.html 对…

使用Docker部署JDK镜像

构建镜像 我们将已经准备好的docker-demo.jar包以及Dockerfile拷贝到虚拟机的/root/demo目录&#xff1a; 然后&#xff0c;执行命令&#xff0c;构建镜像&#xff1a; # 直接指定Dockerfile目录 docker build -t docker-demo:1.0 /root/demo 查看镜像列表&#xff1a; # 查看…

AI专题:5G-A扬帆风正劲,踏AI增长新浪潮

今天分享的是AI系列深度研究报告&#xff1a;《AI专题&#xff1a;5G-A扬帆风正劲&#xff0c;踏AI增长新浪潮》。 &#xff08;报告出品方&#xff1a;开源证券&#xff09; 报告共计&#xff1a;22页 足立连接&#xff0c;拓展算力&#xff0c;双曲线稳步发力 中兴通讯拥…

数据库第五次实验

目录 1 创建数据表 2 创建多个用户 ​​​​​​​3 用户的授权 ​​​​​​​4 用户权限的回收 ​​​​​​​5 角色的创建与授权 ​​​​​​​6 回收角色的权利 ​​​​​​​7 审计的设置 1 创建数据表 SQL语句&#xff1a; use experimentfive; create table…

[UI5 常用控件] 09.IconTabBar,IconTabHeader,TabContainer

文章目录 前言1. IconTabBar1.1 简介1.2 基本结构1.3 用法1.3.1 颜色&#xff0c;拖放&#xff0c;溢出1.3.2 Icons Only , Inner Contents1.3.3 showAll,Count,key,IconTabSeparator 1.3.4 Only Text1.3.5 headerMode-Inline1.3.6 design,IconTabSeparator-icon1.3.7 DensityM…

【NI-DAQm入门】构建应用程序案例1

1.系统框图 2.应用框图 3. 代码结构 3.1 技巧1 使用模拟采样时钟作为编码器的时钟源•(而不是使用隐式) 同步模拟输入和编码 3.2 技巧2 为模拟输入和计数器输入采集样本 写入相同采样点至文件 对齐数据文件 3.3 技巧3 数字读写技巧

C++-手把手教你模拟实现string

1.string的成员变量 模拟实现string只需要三个成员变量&#xff0c;capacity&#xff0c;size&#xff0c;_str&#xff0c;也就是容量&#xff0c;数据大小&#xff0c;指向字符串的指针。 2.string的构造函数 2.1 使用字符串构造 使用字符串来构造一个string类的对象&…

【MySQL】多表关系的基本学习

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-3oES1ZdkKIklfKzq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…