【题目】链表相关算法题

文章目录

  • 一. 合并两个有序链表
    • 题目解析
    • 算法原理
    • 代码编写
  • 二. 相交链表问题
    • 题目解析
    • 算法原理
    • 代码编写
  • 三. 环形链表问题
    • 1. 判断是否有环
    • 2. 计算环的长度
    • 3. 找到环的入口点
  • 四. 反转链表
    • 方法一:边迭代、边逆置
    • 方法二:头插
  • 五. 判断链表是否回文
    • 题目解析
    • 算法原理
    • 代码编写
  • 六、删除排序链表中的重复元素问题
    • 1. 删除排序链表中的重复元素I
    • 2. 删除排序链表中的重复元素II
  • 七. 随机链表的复制
    • 题目解析
    • 算法原理
    • 代码编写


一. 合并两个有序链表


题目解析

在这里插入图片描述

算法原理

同时遍历两个链表,取 val 小的那个节点尾插到新链表中

在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution 
{
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {// 1、预处理(创建哨兵位头节点)ListNode* head, *tail;head = tail = new ListNode();// 2、遍历并合并两个两个链表while(list1 != nullptr && list2 != nullptr){if(list1->val < list2->val) {tail->next = list1;list1 = list1->next;}else{tail->next = list2;list2 = list2->next;}tail = tail->next;}// 3、处理未遍历完的那个链表if(list1 != nullptr) tail->next = list1;else tail->next = list2;// 4、返回最终结果ListNode* ans = head->next;delete head;return ans;}
};

二. 相交链表问题


题目解析

在这里插入图片描述

算法原理

在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution 
{
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {// 1、判断两个链表是否相交 && 计算两个链表的长度int lenA = 1, lenB = 1; //链表长度ListNode *ltA = headA, *ltB = headB; //链表最后一个节点while(ltA && ltA->next) ltA = ltA->next, ++lenA; //寻找A最后一个节点 和 统计链表长度while(ltB && ltB->next) ltB = ltB->next, ++lenB; //寻找B最后一个节点 和 统计链表长度if(ltA != ltB) return nullptr; //判断是否相交// 2、寻找初始相交节点int gap = abs(lenA - lenB); //链表长度差值ListNode *longList = headA, *shortList = headB; //创建长、短链表指针if(lenA < lenB) std::swap(longList, shortList);//确认长、短链表指针while(gap--) longList = longList->next; //长链表先走 gap 步while(longList != shortList) //两个链表同步走{longList = longList->next;shortList = shortList->next;}// 3、返回值return longList; }
};
/*
- 时间复杂度:O(m+n)
- 空间复杂度:O(1)
*/

三. 环形链表问题


1. 判断是否有环


解题思路
在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode ListNode;bool hasCycle(struct ListNode *head) 
{//空链接情况的处理if(!head){return false;}ListNode* fast=head;ListNode* slow=head;//fast一次走两步,为了防止空指针的访问要两个条件的判断while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){return true;}}return false;
}

2. 计算环的长度


算法原理
在这里插入图片描述


3. 找到环的入口点


算法原理
在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*///先记录fast和slow相遇时的节点//在定义一个节点从头开始//二者每次走一步//最后相遇时的节点就是入环节点typedef struct ListNode ListNode;struct ListNode *detectCycle(struct ListNode *head) 
{    ListNode* slow=head;ListNode* fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){ListNode* meet=slow;while(1){if(head==meet){return head;}head=head->next;meet=meet->next;}}}return NULL;
}

四. 反转链表


在这里插入图片描述

方法一:边迭代、边逆置

算法原理
在这里插入图片描述

代码编写

// 方法一:边迭代、边逆置 
class Solution 
{
public:ListNode* reverseList(ListNode* head) {if(!head) return nullptr;// 1、初始化ListNode* n1 = nullptr;ListNode* n2 = head;ListNode* n3 = head->next;// 2、逆置while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3) n3 = n3->next;}// 3、返回值return n1;}
};

方法二:头插

算法原理
在这里插入图片描述

代码编写

class Solution 
{
public:ListNode* reverseList(ListNode* head) {// 1、初始化ListNode* cur = head, *newHead = nullptr;// 2、头插while(cur){ListNode* next = cur->next;cur->next = newHead;newHead = cur;cur = next;}// 3、返回值return newHead;}
};

五. 判断链表是否回文


题目解析

算法原理

在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution 
{
private:ListNode* ReverseList(ListNode* head){if(!head) return nullptr;ListNode* n1 = nullptr, *n2 = head, *n3 = head->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3) n3 = n3->next;}return n1;}public:bool isPalindrome(ListNode* head) {// 1、找到中间节点ListNode* fast, *slow;fast = slow = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}// 2、逆置后半段链表ListNode* half = ReverseList(slow);// 3、比较前后部分链表while(head && half){if(head->val != half->val) return false;head = head->next;half = half->next;}// 4、返回值return true;}
};

六、删除排序链表中的重复元素问题


1. 删除排序链表中的重复元素I


在这里插入图片描述

算法原理
在这里插入图片描述

代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution 
{
public:ListNode* deleteDuplicates(ListNode* head) {// 0、特殊情况处理(保证链表至少有两个节点才做处理)if(head == nullptr || head->next == nullptr) return head;// 1、初始化ListNode* newHead, *tail;  newHead = tail = head;//新链表第一个节点为 headhead = head->next;    //旧链表从第二个节点开始遍历 tail->next = nullptr; //设置新链表中第一个节点的 next 为空  // 2、删除重复元素while(head){ListNode* cur = head;head = head->next;if(cur->val != tail->val){tail->next = cur;tail = cur;tail->next = nullptr;}}// 3、返回值return newHead;}
};

2. 删除排序链表中的重复元素II


在这里插入图片描述

算法原理
在这里插入图片描述
代码编写

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution 
{
public:ListNode* deleteDuplicates(ListNode* head) {// 0、特殊情况处理(保证链表至少有两个节点才做处理)if(head == nullptr || head->next == nullptr) return head;// 1、初始化ListNode* newHead, *tail;  newHead = tail = head;//新链表第一个节点为 headhead = head->next;    //旧链表从第二个节点开始遍历 tail->next = nullptr; //设置新链表中第一个节点的 next 为空  // 2、删除重复元素while(head){ListNode* cur = head;head = head->next;if(cur->val != tail->val){tail->next = cur;tail = cur;tail->next = nullptr;}}// 3、返回值return newHead;}
};

七. 随机链表的复制


题目解析

在这里插入图片描述

算法原理

在这里插入图片描述

代码编写

/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;}
};
*/class Solution 
{
public:Node* copyRandomList(Node* head) {// 1、拷贝节点到原节点的后面Node* cur = head;while(cur){// 初始化Node* copy = new Node(cur->val);Node* next = cur->next;// 链接cur->next = copy;copy->next = next;// 更新curcur = next;}// 2、处理拷贝节点的 random 指针cur = head;while(cur){Node* copy = cur->next;if(cur->random) copy->random = cur->random->next;// 继续迭代原链表的下一个节点cur = cur->next->next;}// 3、拆解链表Node* newHead, *tail; //创造一个哨兵位头节点newHead = tail = new Node(0);cur = head;while(cur){// 初始化Node* copy = cur->next;Node* next = cur->next->next;// 尾插拷贝节点到新链表中tail->next = copy;tail = copy;tail->next = nullptr;// 处理原链表节点cur->next = next;cur = next;}// 4、返回值return newHead->next;}
};

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

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

相关文章

20231201将RK3399的挖掘机开发板在Andorid12系统下的强制横屏

20231201将RK3399的挖掘机开发板在Andorid12系统下的强制横屏 2023/12/1 22:54 【不完美的地方&#xff1a;修改之后不满屏】 百度&#xff1a;rk3399 android12 横屏 不满屏 Android 显示不满屏 build.prop https://blog.csdn.net/weixin_39966398/article/details/105595184?…

深入了解c语言中的结构体

介绍&#xff1a; 在C语言中&#xff0c;结构体是一种用户自定义的数据类型&#xff0c;它允许我们将不同类型的数据组合在一起&#xff0c;形成一个更为复杂的数据结构。结构体可以用来表示现实世界中的实体&#xff0c;如人员、学生、图书等。本篇博客将介绍结构体的基本概念…

LLM:《第 3 部分》从数学角度评估封闭式LLM的泛化能力

一、说明 在 OpenAI 或 Anthropic 等封闭式大型语言模型 (LLM) 领域&#xff0c;对智能和多功能性的真正考验在于它们处理高特异性查询并在响应中表现出独特性的能力。在这篇博客中&#xff0c;我的目标是提供测试这些模型泛化能力的机制。 封闭式LLM意味着您不知道训练语料库的…

electerm下载和安装

electerm下载和安装 一、概述 electerm 是一款免费开源、基于electron/ssh2/node-pty/xterm/antd/ subx等libs的终端/ssh/sftp客户端(linux, mac, win)。 而且个人觉得electerm界面更好看一些&#xff0c;操作都是类似的。 二、下载安装 下载地址&#xff1a;https://elec…

HarmonyOs 4 (二) HelloWord

目录 一 开发工具下载安装1.1 下载安装包1.2 下载相关依赖 二 开发者注册与个人实名认证三 第一个程序2.1 创建第一个程序2.2 认识开发者界面2.3 目录结构认识2.3.1 父目录认识2.3.2 AppScope 目录2.3.3 entry目录2.3.3.1 ets 目录2.3.3.2 resources目录 2.3.4 认识配置文件2.3…

【高效开发工具系列】驼峰下划线互转

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

java基于springboot框架的中小企业人力资源管理系统的设计及实现+jsp

&#xff08;1&#xff09;员工信息管理&#xff1a;员工的基本信息&#xff0c;人员编制&#xff0c;岗位管理&#xff0c;人员流动管理&#xff08;老员工转出&#xff0c;辞职&#xff0c;退休等&#xff09;&#xff0c;职工业绩考核归公管理&#xff0c;工人工种管理。 &…

Hdoop学习笔记(HDP)-Part.11 安装Kerberos

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

Jinja2使用Layui报 “d is not defined“

问题出现场景在使用Jinja2渲染Layui的表格时候&#xff0c;要做自定义templte的传入 Jinja2这块本来就是支持 {{ }} 插值的模板语言&#xff0c;所以这块的第一种渲染方式会冲突 所以只能用函数返回代码块进行填充&#xff0c;不能使用插值&#xff0c;只能拼接字符串 templt…

unity3d c#代码变更文本颜色,可选多参数,委托invoke延迟调用函数

[SerializeField] private Text warning; Color color ;warningOpen("注册成功", closeTime: 1.5f);warningOpen("登录成功", "green", 1.5f);public void warningOpen( string warn, string tmp"red", float closeTime5f ){warnin…

PVE系列-CT容器安装openwrt X86的极简方法

下载推荐&#xff1a;https://openwrt.ai/ 使用环境PVE8.0&#xff0c;openwrt是以上网址的最新版&#xff0c;内涵及其丰富组件。 问题来源&#xff1a; 在PVE虚拟机可以很方便的使用img文件&#xff0c;转换qm 成一个硬盘文件&#xff0c;加入到虚拟机也就完成了&#xff0c…

Docker下安装Tomcat

目录 Tomcat简介 Tomcat安装 免修改版Tomcat安装 Tomcat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持&#x…