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

【数据结构】LeetCode160.相交链表 138.随即链表复制 牛客——链表回文问题

文章目录

    • 一、相交链表问题
      • 问题描述
      • 解题思路分析
        • 思路一:暴力遍历法
        • 思路二:双指针对齐法(最优解)
    • 二、链表的回文结构
      • 问题描述
      • 解题思路
      • 完整代码
    • 三、 随即链表的复制
      • 问题描述
      • 解题思路
      • 复杂度分析

一、相交链表问题

问题描述

给定两个单链表,判断它们是否相交,若相交则返回相交的节点。(注意:判断依据是节点地址是否相同,而非节点值,因为节点值可能存在重复。)


在这里插入图片描述

解题思路分析

思路一:暴力遍历法
  • 方法:遍历链表A,对于A中的每一个节点,遍历整个链表B,检查是否存在地址相同的节点。
  • 时间复杂度:O(M*N)(若两链表长度分别为M和N)
  • 空间复杂度:O(1)
  • 缺点:效率低,不适用于长链表。
思路二:双指针对齐法(最优解)
  • 方法:
    1. 分别遍历两个链表,计算各自长度。
    2. 求出两链表长度差 gap
    3. 让较长的链表的指针先移动 gap 步。
    4. 然后两个指针同时移动,逐个比较节点地址,第一个相同的节点即为交点。
  • 时间复杂度:O(M + N)
  • 空间复杂度:O(1)
  • 优点:高效,适用于任意长度的链表。

在这里插入图片描述

思路2的时间复杂度更低,所以我们选择思路2

具体代码如下

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* curA=headA,*curB=headB;int lenA=1,lenB=1;while(curA->next){curA=curA->next;lenA++;}while(curB->next){curB=curB->next;lenB++;}int gap=abs(lenA-lenB);//假设法 先假设A长struct ListNode* longList=headA;struct ListNode* shortList=headB;if(lenA<lenB){longList=headB;shortList=headA;}while(gap--){longList=longList->next;}while(longList){if(longList==shortList)return longList;longList=longList->next;shortList=shortList->next;}return NULL;
}

二、链表的回文结构

问题描述

判断一个单链表是否为回文结构。即正着读和反着读都一样

在这里插入图片描述

解题思路

回文链表判断的关键在于对称性验证。我们可以通过以下步骤实现:

  1. 找到中间节点:使用快慢指针法,快指针每次走两步,慢指针每次走一步,当快指针到达末尾时,慢指针正好在中间。
  2. 反转后半部分链表:从中间节点开始,将后半部分链表反转。
  3. 比较前后两部分:从头节点和反转后的中间节点开始,逐个比较节点值是否相同。

完整代码

class PalindromeList {
public://寻找中间节点
struct ListNode* middleNode(struct ListNode* head) {// 初始化快慢指针struct ListNode* slow = head;struct ListNode* fast = head;// 移动指针直到fast到达链表末尾while (fast != NULL && fast->next != NULL) {slow = slow->next;      // 慢指针每次移动一步fast = fast->next->next; // 快指针每次移动两步}return slow; // 慢指针指向中间节点
}//反转链表
struct ListNode* reverseList(struct ListNode* head) {struct ListNode* n1, *n2, *n3;n1 = NULL;n2 = head;if (n2)n3 = n2->next;while (n2) {n2->next = n1;n1 = n2;n2 = n3;if (n3)n3 = n3->next;}return n1;
}bool chkPalindrome(ListNode* A) {// write code herestruct ListNode*mid=middleNode(A);struct ListNode*rmid=reverseList(mid);while(rmid&&A){if(rmid->val!=A->val)return false;rmid=rmid->next;A=A->next;}return true;
}};

三、 随即链表的复制

问题描述

实现一个函数,复制一个含有随机指针的链表。随机指针可以指向链表中的任何节点或为空。

在这里插入图片描述

解题思路

常规链表的复制很简单,但随机指针的存在使得问题复杂化。因为随机指针可能指向尚未复制的节点。我们可以通过以下三步解决:

  1. 插入拷贝节点:在原链表的每个节点后插入一个拷贝节点,值与原节点相同。
  2. 设置随机指针:拷贝节点的随机指针应指向原节点随机指针所指节点的下一个节点(即其拷贝)。
  3. 分离链表:将混合链表分离为原链表和拷贝链表。

在这里插入图片描述

struct Node* copyRandomList(struct Node* head) {//拷贝节点插到原节点后边
struct Node*cur=head;while(cur)
{struct Node* copy=(struct Node*)malloc(sizeof(struct Node));//分配内存copy->next=cur->next;cur->next=copy;copy->val=cur->val;cur=copy->next;//cur走到原链表的下一个  
}
//控制randomcur=head;
while(cur)
{struct Node* copy = cur->next;if(cur->random==NULL)//不要写成random==NULL{copy->random=NULL;}else{copy->random=cur->random->next;//核心代码}cur=copy->next;
}//把拷贝链表尾插起来
struct Node* copyhead=NULL,*copytail=NULL;cur=head;
while(cur)
{struct Node*copy=cur->next;if(copytail==NULL){copyhead=copytail=copy;}else{copytail->next=copy;copytail=copytail->next;}cur=copy->next;
}
return copyhead;
}

复杂度分析

  • 时间复杂度:O(N),三次遍历链表。
  • 空间复杂度:O(1),除了返回的拷贝链表外,仅使用了常数个额外指针。
http://www.xdnf.cn/news/18910.html

相关文章:

  • SQL每日一练
  • 盲盒经济新风口:盲盒抽谷机小程序系统开发全解析
  • 深度学习-----《PyTorch神经网络高效训练与测试:优化器对比、激活函数优化及实战技巧》
  • Telematics Control Unit(TCU)的系统化梳理
  • 数据结构:红黑树(Red-Black Tree)
  • git开发基础流程
  • Springboot应用如何与SkyWalking集成,并使用Docker进行发布
  • Python爬虫实战:研究amazon-scrapy,构建亚马逊电商数据采集和分析系统
  • 扣子智能体商业化卡在哪?井云系统自动化交易+私域管理,闭环成交全流程拆解
  • 小程序开发指南(四)(UI 框架整合)
  • 机器视觉的3C玻璃盖板丝印应用
  • three.js+WebGL踩坑经验合集(8.3):合理设置camera.near和camera.far缓解实际场景中的z-fighting叠面问题
  • 如何在IDEA中使用Git
  • MyBatis-Plus 快速入门 -常用注解
  • 使用阿里云实现短信注册
  • SAVITECH盛微先进SAVIAUDIO音频解码芯片方案与应用
  • ValueTask 实战指南:解锁 .NET 异步编程的性能秘密
  • window显示驱动开发—混合系统 DDI 和 dList DLL 支持
  • 【P2P】P2P主要技术及RELAY服务实现
  • mac设置鼠标滚轮方向
  • 让清洁更智能,让城市更美好
  • 20、DMA----释放CPU压力,加快传输
  • 无人机航拍数据集|第30期 无人机腰果成熟度目标检测YOLO数据集3098张yolov11/yolov8/yolov5可训练
  • Day8--HOT100--160. 相交链表,206. 反转链表,234. 回文链表,876. 链表的中间结点
  • 艾利特石油管道巡检机器人:工业安全的智能守护者
  • 高通平台wifi--p2p issue
  • leetcode 17.04 消失的数字
  • 理解Vuex的辅助函数,分析mapState、mapGetters、mapMutations和mapActions各个应用场景
  • SQL 语句拼接在 C 语言中的实现与安全性分析
  • 大模型应用实战:构建企业知识库 RAG 系统(含权限控制 + 多轮对话)