【数据结构】链表常见题目

文章目录

  • 链表
    • 合并两个有序链表
    • 反转链表
    • 复制带随机指针的链表
    • 环形链表
    • 环形链表II
    • 相交链表
    • 移除链表元素
    • 链表中倒数第k个节点
    • 链表分割
    • 链表的回文结构
    • 链表的中间节点
    • 旋转链表
    • 链表排序
    • 链表求和 (逆序求)
    • 链表求和II (正序求)
    • 重排链表
    • 奇偶链表
    • 反转链表II <==> 链表内指定区间反转
    • 删除链表中的节点
    • 删除有序链表当中重复的元素I
    • 删除有序链表当中重复的元素II
    • 合并K个升序链表
    • K个一组反转链表
    • 交换链表中的节点
    • 二进制链表转整数
    • 链表随机节点

链表

合并两个有序链表

https://leetcode.cn/problems/merge-two-sorted-lists/

1.定义一个哨兵位节点和一个tail节点标志尾节点

2.遍历两条有序链表,谁小就链接谁

3.最后还剩一条链表是没有遍历完成的,那么就让tail节点链接它

class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {//1.新建哨兵位节点ListNode* phead = new ListNode(-1);ListNode* tail = phead;//2.谁小就链接谁while(list1 && list2){if(list1->val > list2->val){tail->next = list2;tail = list2;list2 = list2->next;}else {tail->next = list1;tail = list1;list1 = list1->next;}}//3.判断谁还没有链接完if(list1) tail->next = list1;if(list2) tail->next = list2;return phead->next;}
};

反转链表

https://leetcode.cn/problems/reverse-linked-list/description/

prev:记录前一个节点 cur:当前遍历到的节点 next:保存cur的下一个节点

  • 先保存下一个节点 然后更改cur的指向,指向前一个节点
  • 然后迭代往后走
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;//记录前一个节点ListNode* cur = head;//记录当前节点ListNode* next = nullptr;//记录下一个节点while(cur){next = cur->next;//先保存下一个节点cur->next = prev;//更改当前节点指向//prev cur next 迭代往后走prev = cur;cur = next;}return prev;}
};

复制带随机指针的链表

https://leetcode.cn/problems/copy-list-with-random-pointer/

1.在原链表节点之后拷贝一个节点

image-20230816094513759

2.处理拷贝节点的random指针

  • 注意:拷贝节点的random指针指向的节点是其原链表节点的random指针指向的节点的下一个节点
  • 坑点:有可能cur->random是空,也就是原来节点的random指针为空,那么当前拷贝节点的random指针也应该为空,否则cur->random->next 就会对空指针解引用!

image-20230816094637865

3.分离两条链表

  • 最好定义一个哨兵位节点和一个tail指针用于标记链接拷贝链表,
  • cur CopyCur next三者的关系重新处理

image-20230816094751726

class Solution {public:Node* copyRandomList(Node* head) {if(head == nullptr ) return nullptr;//1.在原节点后面copy一个节点Node* cur = head;while(cur){Node* copy = new Node(cur->val);//拷贝节点Node* next = cur->next;//cur copy next 链接cur->next = copy;copy->next = next;cur = next;//继续复制下一个节点}//2.处理拷贝节点的random指针cur = head;while(cur){Node* curCopy = cur->next;//cur的拷贝节点curCopy->random = cur->random == nullptr?nullptr:cur->random->next;cur = curCopy->next;}//3.拆离拷贝链表cur = head;Node* pnewHead = new Node(-1);//哨兵位Node* tail = pnewHead;while(cur){//cur copyCur next  Node* copyCur = cur->next;Node* next = copyCur->next;copyCur->next = nullptr;//让拷贝节点独立存在tail->next = copyCur;tail = tail->next;//重新处理链接关系,向后走cur->next = next;cur = next;}return pnewHead->next;}
};

环形链表

https://leetcode.cn/problems/linked-list-cycle/description/

方法:使用快慢指针,二者从头开始走,一个一次走两步,一个一次走一步,当二者相遇的时候,说明有环

class Solution {
public:bool hasCycle(ListNode *head) {//链表为空//注意:一个节点也能成环! 自己指向自己if(!head) return false;//快慢指针ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇  注意:该条件不能放在上面!!!因为最初fast和slow都指向head,该条件应该放在下面if(slow == fast) return true;}return false;}
};

延申1:fast一次走两步,slow一次走一步,为什么一定能相遇?会不会在环里错过,永远遇不上

结论:slow一次走一步,fast一次走两步,如果存在环,slow和fast一定会在环内相遇

1.slow和fast,如果有环,一定是fast先进环,这时slow走了入环前距离的一半

2.随着slow进环,fast已经在环里面走了一段距离了(距离的多少跟环的大小有关)

  • 假设slow进环的时候,slow和fast的距离为N,fast开始追赶slow

3.slow一次走一步,fast一次走两步,二者的距离变化为:N N- 1 N -2 … 0,当二者的距离变为0的时候,就是相遇了

延申2:fast一次走n步(n>2),slow一次走一步,fast和slow能相遇吗

结论:fast一次走n步(n>2),slow一次走一步,不一定会相遇

  • 假设有环,fast一次走n步,slow一次走1步,fast和slow的距离不断减少n-1步

例子:假设fast一次走3步,如果slow进环之后,slow和fast的距离为N

如果N为偶数,那么二者之间的距离变化为:N N - 2 N - 4 … 2 0,此时二者相遇

如果N为计数,那么二者之间的距离变化为:N N - 2 N - 4 … 1 -1 ,二者距离变为-1,意味着fast超越了slow,此时fast和slow的距离为C -1 (假设C为环的大小)

  • 如果C - 1 为偶数,那么下一轮fast可以追上slow,二者相遇
  • 如果C - 1 为奇数,那么二者永远追不上

环形链表II

https://leetcode.cn/problems/linked-list-cycle-ii/description/

做法:

1.先看是否有环,快慢指针,fast一次走两步,slow一次走一步,如果存在环,fast和slow一定会相遇

2.假设相遇点为meetnode,一个指针从链表的头开始走,一个指针从相遇点开始走,二者一次走一步,当二者相遇的时候,该位置就是入环节点

image-20230816102819793

class Solution {
public:ListNode *detectCycle(ListNode *head) {if(!head) return nullptr;//快慢指针ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇  注意:该条件不能放在上面!!!因为最初fast和slow都指向head,该条件应该放在下面if(slow == fast) {//分别从相遇点和链表头开始走,一次走一步  此时相遇就是入环位置ListNode* meet = slow;slow = head;while(slow != meet) {slow = slow->next;meet = meet->next;}return meet;}}return nullptr; //没有环}
};

相交链表

https://leetcode.cn/problems/intersection-of-two-linked-lists/description/

方法1:将A链表的所有节点放到容器当中(要放地址,不能放值),然后遍历B链表,看能否在容器当中找到该元素,如果找到,那么该节点就是相交节点

class Solution {
public://方法1:用容器保存其中一个链表的节点,然后遍历另外一个链表进行比对ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {multiset<ListNode*> s;ListNode* cur = headA;while(cur) {s.insert(cur);cur = cur->next;}cur = headB;while(cur){cout << cur->val << endl;if(s.find(cur) != s.end()) return cur;cur = cur->next;}return nullptr;//不相交}
};

方法2:A中的每个结点和B分别比较(B和A比较也可以),看二者的地址是否一致 - O(N*M)

class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* curA = headA;ListNode* curB = headB;while(curA) //确定一个A节点{curB = headB;while(curB)//遍历整条B链表{if(curA == curB){return curA;}curB = curB ->next;}curA = curA->next;}return nullptr;}
};

方法3:

1.先统计两条链表的长度,假设二者长度差距为gap

2.长链表先往后走gap步,然后长短链表一起往后走,如果相遇,那么就是相交节点

class Solution {public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if(!headA || !headB) return nullptr;//1.统计两条链表的长度int lenA = 0;int lenB = 0;ListNode* cur = headA;while(cur)  lenA++,cur = cur->next;cur = headB;

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

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

相关文章

(二)掌握最基本的Linux服务器用法——Linux下简单的C/C++ 程序、项目编译

1、静态库与动态库 静态库(Static Library)&#xff1a;静态库是编译后的库文件&#xff0c;其中的代码在编译时被链接到程序中&#xff0c;因此它会与程序一起形成一个独立的可执行文件。每个使用静态库的程序都会有自己的库的副本&#xff0c;这可能会导致内存浪费。常用后缀…

opencv简单使用

cv2库安装&#xff0c; conda install opencv-python注意cv2使用时&#xff0c;路径不能有中文。&#xff08;不然会一直’None’ _ update # 处理中文路径问题 def cv_imread(file_path): #使用之前需要导入numpy、cv2库&#xff0c;file_path为包含中文的路径return cv2.imd…

idea入门与maven配置的一些介绍

idea入门与maven配置的一些介绍 1.确保Java和Maven已安装2.创建一个新的Maven项目3.导航到要创建项目的目录配置Maven4.配置项目的pom.xml文件5.配置其他Tomcat和设置jdk6.构建和运行项目 关于idea入门基础配置 步骤1&#xff1a;安装IntelliJ IDEA 首先&#xff0c;从IntelliJ…

计算机竞赛 python+大数据校园卡数据分析

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度学习车牌识别系统实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&am…

记录一个编译TubeTK时的报错:at_check问题

在使用如下命令安装TubeTK的cuda_nms时&#xff0c;报了一个错误&#xff0c;记录一下这个错误和解决办法 (base) redmeryredmery:~/Desktop/MOT/TubeTK/post_processing/nms$ python setup.py build_ext --inplace因为这个命令是在/home/redmery/Desktop/MOT/TubeTK/install/…

Talk | ACL‘23 杰出论文奖上海交通大学吴蔚琪:预训练语言模型对本体知识的记忆与理解

本期为TechBeat人工智能社区第523期线上Talk&#xff01; 北京时间8月17日(周四)20:00&#xff0c;上海交通大学硕士研究生—吴蔚琪的Talk已准时在TechBeat人工智能社区开播&#xff01; 她与大家分享的主题是: “预训练语言模型对本体知识的记忆与理解”&#xff0c;分享了预训…

Python入门【TCP建立连接的三次握手、 TCP断开连接的四次挥手、套接字编程实战、 TCP编程的实现、TCP双向持续通信】(二十七)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

【c语言】通讯录(动态版+文件+背景音乐)含源码

开饭了&#xff0c;之前写的通讯录&#xff0c;是否会有人觉得申请1000人的空间是不是有点用不上呀&#xff0c;怎么才能做到要多少申请多少个呢&#xff1f;&#xff1f;我们学完动态内存管理&#xff0c;和文件的相关操作&#xff0c;终于可以继续完善我们的通讯录了 船新版本…

数据结构:二叉树的递归实现(C实现)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》 文章目录 前言一、树的概念二、二叉树二叉树的概念二叉树的性质 三、二叉树链式结构实现二叉树节点定义创建二叉树节点遍历二叉树先序遍历二叉树(BinaryTreePrevOrder)中序遍历二叉树(BinaryTree…

Air780EG —— 合宙4G定位解决方案

定位模式&#xff1a; 外部单片机控制模式(常见于AT固件客户)&#xff1a; 开机 -> 搜星 -> 定位成功 -> 上报 -> 关机 780E自行控制模式(常见于二次开发客户&#xff0c;AT用户也可以使用): 开机 -> 搜星 -> 定位成功 -> 模块休眠&#xff0c;关闭GP…

亿发创新中医药信息化解决方案,自动化煎煮+调剂,打造智能中药房

传统中医药行业逐步复兴&#xff0c;同时互联网科技和人工智能等信息科技助力中医药行业逐步实现数字化转型。利用互联网、物联网、大数据等科技&#xff0c;实现现代科学与传统中医药的结合&#xff0c;提供智能配方颗粒调配系统、中药自动化调剂系统、中药煎配智能管理系统、…

如何切换goland之中的版本号(升级go 到1.20)

go 安装/版本切换_go 切换版本_云满笔记的博客-CSDN博客 用brew就行&#xff1a; echo export PATH"/opt/homebrew/opt/go1.20/bin:$PATH" >> ~/.zshrc

Linux6.40 Kubernetes 配置资源管理

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes 配置资源管理一、Secret1.Secret 四种类型1&#xff09;kubernetes.io/service-account-token2&#xff09;Opaque3&#xff09;kubernetes.io/dockerconfigjson4&#xff09;kubernetes.io/tls 2.Pod 需要先引用才能使用某…

React入门 jsx学习笔记

一、JSX介绍 概念&#xff1a;JSX是 JavaScript XML&#xff08;HTML&#xff09;的缩写&#xff0c;表示在 JS 代码中书写 HTML 结构 作用&#xff1a;在React中创建HTML结构&#xff08;页面UI结构&#xff09; 优势&#xff1a; 采用类似于HTML的语法&#xff0c;降低学…

因果推断(四)断点回归(RD)

因果推断&#xff08;四&#xff09;断点回归&#xff08;RD&#xff09; 在传统的因果推断方法中&#xff0c;有一种方法可以控制观察到的混杂因素和未观察到的混杂因素&#xff0c;这就是断点回归&#xff0c;因为它只需要观察干预两侧的数据&#xff0c;是否存在明显的断点…

【C++入门到精通】C++入门 —— list (STL)

阅读导航 前言一、list简介1.概念2.特点 二、list的使用1.list的构造2.常见的操作⭕std::list类型的增、删、查、改 三、list与vector的对比温馨提示 前言 文章绑定了VS平台下std::list的源码&#xff0c;大家可以下载了解一下&#x1f60d; 前面我们讲了C语言的基础知识&…

C语言实例_获取文件MD5值

一、MD5介绍 MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数算法。将任意长度的数据作为输入&#xff0c;并生成一个唯一的、固定长度&#xff08;通常是128位&#xff09;的哈希值&#xff0c;称为MD5值。MD5算法以其高度可靠性和广泛应用而闻名…

全球磁强计市场价值约为16.2亿美元,预测期内将以超过5.21%的增长率增长

磁强计是一种用于测量磁场强度和方向的仪器。它可以检测和测量地球磁场、物体的磁性、地下矿藏、磁性材料等。磁强计在地球科学、物理学、地质学、勘探、矿业等领域具有广泛的应用。 根据阿谱尔&#xff08;APO&#xff09;的统计及预测&#xff0c;2022年全球磁强计市场价值约…

ts与vue

ts与Vue 如果你已经学习了typeScript,但不知道如何在vue项目中使用&#xff0c;那么这篇文章将会很适合你。参考千峰教育 kerwin视频 1.会自动推导&#xff0c;隐士推导。提示 类型系统。 独立模块。 isolatedModules选项&#xff1a;是否配置为独立的模块。 减少报错 let …