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

反转链表、链表内指定区间反转

反转链表

给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。以上转换过程如下图所示:

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

输入:{1,2,3}
返回值:{3,2,1}

好久好久没有刷题了,这一年大多在写Shell脚本或者Python脚本去了,已经忘记自己是C++起家的了,好几天前大页表吴同学找了两个题目说有意思让我试一下,害,当天晚上没做出来,有时间了再看这题目,其实就是头插法,尾插法是正序,头插法就是反转了,代码附上,关键是第二题。

/*** struct ListNode {*	int val;*	struct ListNode *next;*	ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <cstddef>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param head ListNode类 * @return ListNode类*/ListNode* ReverseList(ListNode* head) {// write code hereListNode* Rs = NULL;ListNode* Next = head->next;ListNode* Cur = head;while(Cur){Cur->next = Rs;Rs = Cur;Cur = Next;Next = Next->next;}return Rs;}
};

链表内指定区间反转

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转。
在这里插入图片描述
这个题目首先我的想法就是把第一题反转的函数用上,然后把只需要截断反转再连接就可以了。我们使用示例{1,2,3,4,5},2,4。

第一种思路:

首先是找到需要反转的区间链表,

ListNode* dummyNode = new ListNode(-1);
dummyNode->next = head;ListNode* pre = dummyNode;
for(int i=0;i<m-1;i++){pre = pre->next;
}ListNode* rightNode = pre ;
for(int i=0;i<n-m+1;i++){rightNode = rightNode->next;
}ListNode* leftNode = pre->next;//leftNode = {2,3,4,5}
ListNode* cur = rightNode->next;//后置链表 cur = {5}//截断链表
pre->next=NULL;//前置链表截断 pre = {1}
rightNode->next=NULL;//后置链表截断 leftNode = {2,3,4}

反转函数:

ListNode* ReverseList(ListNode* head) {// write code hereListNode* Rs = NULL;ListNode* Next = head->next;ListNode* Cur = head;while(Cur){Cur->next = Rs;Rs = Cur;Cur = Next;Next = Next->next;}return Rs;
}

得到反转后的区间后,前置部分直接链接,后置部分通过遍历到反转区间链表的最后一个元素指向最后一部分。

ListNode* mid = ReverseList(leftNode);//mid = {4,3,2}pre->next = mid;
while (mid ->next)mid = mid -> next;
mid ->next = cur;
return dummyNode->next;

完整代码:

/*** struct ListNode {*  int val;*  struct ListNode *next;*  ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <ios>
#include <iostream>
using namespace std;
class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param head ListNode类* @param m int整型* @param n int整型* @return ListNode类*/ListNode* ReverseList(ListNode* head) {// write code hereListNode* Rs = NULL;ListNode* Next = head->next;ListNode* Cur = head;while(Cur){Cur->next = Rs;Rs = Cur;Cur = Next;Next = Next->next;}return Rs;}ListNode* reverseBetween(ListNode* head, int m, int n) {// write code hereListNode* dummyNode = new ListNode(-1);dummyNode->next = head;ListNode* pre = dummyNode;for(int i=0;i<m-1;i++){pre = pre->next;}ListNode* rightNode = pre ;for(int i=0;i<n-m+1;i++){rightNode = rightNode->next;}ListNode* leftNode = pre->next;ListNode* cur = rightNode->next;pre->next=NULL;rightNode->next=NULL;ListNode* mid = ReverseList(leftNode);pre->next = mid;while (mid ->next)mid = mid -> next;mid ->next = cur;return dummyNode->next;}
};

第二种思路:

第二种思路就是反转函数返回一个链表有点多此一举,只需要在反转函数里对链表进行操作即可。
反转函数:

void ReverseList(ListNode* head) {// write code hereListNode* Rs = NULL;ListNode* Next = head->next;ListNode* Cur = head;while(Cur){Cur->next = Rs;Rs = Cur;Cur = Next;Next = Next->next;}
}

反转后:

//反转前 leftNode = {2,3,4} rightNode = {4}
ReverseList(leftNode);
//反转后 leftNode = {2} rightNode = {4,3,2}
pre->next = rightNode;
leftNode->next = cur;
return dummyNode->next;

完整代码:

/*** struct ListNode {*  int val;*  struct ListNode *next;*  ListNode(int x) : val(x), next(nullptr) {}* };*/
#include <ios>
#include <iostream>
using namespace std;
class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param head ListNode类* @param m int整型* @param n int整型* @return ListNode类*/void ReverseList(ListNode* head) {// write code hereListNode* Rs = NULL;ListNode* Next = head->next;ListNode* Cur = head;while(Cur){Cur->next = Rs;Rs = Cur;Cur = Next;Next = Next->next;}}ListNode* reverseBetween(ListNode* head, int m, int n) {// write code hereListNode* dummyNode = new ListNode(-1);dummyNode->next = head;ListNode* pre = dummyNode;for(int i=0;i<m-1;i++){pre = pre->next;}ListNode* rightNode = pre ;for(int i=0;i<n-m+1;i++){rightNode = rightNode->next;}ListNode* leftNode = pre->next;ListNode* cur = rightNode->next;pre->next=NULL;rightNode->next=NULL;ReverseList(leftNode);pre->next = rightNode;leftNode->next = cur;return dummyNode->next;}
};

链表介绍

链表(Linked List)是一种线性数据结构,其中的元素(通常称为节点)按顺序排列,每个节点包含两部分信息:存储数据的部分和指向下一个节点的指针或引用。链表中的每个节点通过指针连接在一起,因此它不需要在内存中连续存储。链表有几种常见的形式:

  • 单向链表(Singly Linked List):每个节点只包含一个指向下一个节点的指针,链表是单向的,无法向后遍历。
  • 双向链表(Doubly Linked List):每个节点包含两个指针,一个指向下一个节点,另一个指向前一个节点,因此可以双向遍历。
  • 循环链表(Circular Linked List):链表的最后一个节点指向链表的第一个节点,形成一个环。

链表的优点:

  • 动态内存分配:链表不需要预先定义大小,可以根据需要动态增长或缩小。
  • 插入和删除操作:链表的插入和删除操作可以在常数时间内完成,特别是对于已知位置的节点。

链表的缺点:

  • 随机访问:由于链表的元素不在连续的内存位置,因此不能像数组一样通过索引进行随机访问,必须从头节点开始遍历。

链表广泛应用于实现队列、栈以及某些复杂数据结构,如图和哈希表的底层实现。

http://www.lryc.cn/news/488334.html

相关文章:

  • Debezium系列之:Debezium3版本使用快照过程中的指标
  • 第一讲,Opencv计算机视觉基础之计算机视觉概述
  • 数据结构(双向链表——c语言实现)
  • 【新人系列】Python 入门(十一):控制结构
  • 群核科技首次公开“双核技术引擎”,发布多模态CAD大模型
  • 【AI大模型引领变革】探索AI如何重塑软件开发流程与未来趋势
  • linux 常用命令指南(存储分区、存储挂载、docker迁移)
  • 用pyspark把kafka主题数据经过etl导入另一个主题中的有关报错
  • Redis的过期删除策略和内存淘汰机制以及如何保证双写的一致性
  • 异常处理:import cv2时候报错No module named ‘numpy.core.multiarray‘
  • C++手写PCD文件
  • 优选算法(双指针)
  • 【保姆级】Mac上IDEA卡顿优化
  • python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具
  • pytest 接口串联场景
  • Springboot项目搭建(2)-用户详细信息查询
  • Stable Diffusion的加噪和去噪详解
  • 解决 Gradle 报错:`Plugin with id ‘maven‘ not found` 在 SDK 开发中的问题
  • EMD-KPCA-Transformer多变量回归预测!分解+降维+预测!多重创新!直接写核心!
  • 前端 px、rpx、em、rem、vh、vw计量单位的区别
  • OceanBase数据库产品与工具介绍
  • 学习threejs,对模型多个动画切换展示
  • 【Bug合集】——Java大小写引起传参失败,获取值为null的解决方案
  • Python爬虫:如何从1688阿里巴巴获取公司信息
  • 单片机学习笔记 2. LED灯闪烁
  • 折叠光腔衰荡高反射率测量技术的matlab模拟理论分析
  • ubuntu 16.04 中 VS2019 跨平台开发环境配置
  • C语言第13节:指针(3)
  • java:简单小练习,面积
  • @Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)