【OJ】链表刷题

个人主页 : zxctsclrjjjcph
文章封面来自:艺术家–贤海林
如有转载请先通知

题目

  • 1. 相交链表(160)
    • 1.1 暴力求解
      • 1.1.1 分析
      • 1.1.2 代码实现
    • 1.2 优化后求解
      • 1.2.1 分析
      • 1.2.2 代码实现
  • 2. 随机链表的复制(138)
    • 2.1 分析
    • 2.2 代码实现

1. 相交链表(160)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1 暴力求解

1.1.1 分析

题目中描述既要判断是否相交,还要找交点。
把A链表中的所有节点依次在B中找一边。
为了防止在遍历链表时头节点丢失,先记录一下AB头节点:

    struct ListNode* begin1 = headA;
    struct ListNode* begin2 = headB;

先取A的节点,在B链表中遍历一遍,判断B中节点与A是否相交,如果相交,直接返回A的节点,如果不相交,B节点继续往后走。
在这里插入图片描述
当A的第一个节点在B中没有找到相交时,A节点就往后走,继续像第一个节点判断方式一样。不过这里得注意一下,再次访问B链表时候,B的走的节点又得从头节点开始begin2 = headB
当A链表中所有节点都访问完了后,B都没有与之相交的,就返回NULL

1.1.2 代码实现

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
    struct ListNode* begin1 = headA;
    struct ListNode* begin2 = headB;
    while (begin1)
    {
        begin2 = headB;
        while (begin2)
        {
            if (begin1 == begin2)
                return begin1;
            begin2 = begin2->next;
        }
        begin1 = begin1->next;
    }
    return NULL;
}

在这里插入图片描述

1.2 优化后求解

暴力求解虽然简单,但是时间复杂度太高为O(n^2),优化一下代码,使得时间复杂度到O(n)。

1.2.1 分析

可以先判断是否相交,如果A和B两个链表的尾节点的地址都相同,那么就A和B两个链表相交。如果如果A和B两个链表的尾节点的地址不相同,那么就A和B两个链表不相交。
如果相交那么交点怎么求呢?
先求出A和B两个链表的长度,

  while(begin1->next)
   {
        lenA++;
        begin1=begin1->next;
   } 

   while(begin2->next)
   { 
        lenB++;
        begin2=begin2->next;
    }

让长的链表先走两个链表相查的节点数,

    while(n--)
    {
        longlist=longlist->next;
    }

两个链表再同时走,第一个相同的就是交点。

    while(longlist!=shortlist)
    {
        longlist=longlist->next;
        shortlist=shortlist->next;
    }
    return longlist;

1.2.2 代码实现

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
   struct ListNode *begin1=headA;
   struct ListNode *begin2=headB;
   int lenA=1;
   int lenB=1;
   while(begin1->next)
   {
        lenA++;
        begin1=begin1->next;
   } 

   while(begin2->next)
   { 
        lenB++;
        begin2=begin2->next;
    }
    if(begin1!=begin2)
    {
        return NULL;
    }

    int n=abs(lenA-lenB);
    struct ListNode *longlist=headA;
    struct ListNode *shortlist=headB;
    if(lenA<lenB)
    {
        longlist=headB;
        shortlist=headA;
    }
    
    while(n--)
    {
        longlist=longlist->next;
    }

     while(longlist!=shortlist)
    {
        longlist=longlist->next;
        shortlist=shortlist->next;
    }
    return longlist;
}

在这里插入图片描述

2. 随机链表的复制(138)

在这里插入图片描述

2.1 分析

这里链表里面包含单链表和随机指针,而随机指针指向链表任意节点或者为空。
在这里插入图片描述

对于节点的拷贝就是申请节点放原节点值任何尾插就行,复制链表倒是容易的。这里主要就是考虑随机指针怎么处理。
如果记录值让随机指针指向,可能会有多个相同的值。所以这里可以记录这个random出现的位置,看看是第几个用i记录,这样就不会出现多个随机指针指向同一个节点。如果每次复制节点都要找第i个,每个找random都是N,那么时间复杂度就是O(N^2)。时间复杂度太高了,优化一下。
在这里插入图片描述
第一步:可以把拷贝的节点都放在原节点的后面,也就是这样:
在这里插入图片描述

这样能方便找到原节点与random的关系。

    while(cur)
    {
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
        copy->next=cur->next;
        cur->next=copy;
        
        cur=copy->next;
    }

在这里插入图片描述
第二步:处理copy节点的random。
再从头开始走第二遍,copy节点每次都等于cur节点的next。
如果cur的random为空,copy节点的random也为空。
如果不是空,copy的random就是cur的random的next。

    cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;
        }
       cur=copy->next;  
    }

在这里插入图片描述
第三步:copy节点解下来尾插
出现申请一个新头节点,任何将copy节点一个一个取下来尾插,最后返回新的头节点。

    struct Node* newhead=NULL,*tail=NULL;
    cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;
        if(tail==NULL)
        {
            newhead=tail=copy;
        }
        else
        {
            tail->next=copy;
            tail=tail->next;
        }
        cur->next=next;
        cur=next;
    }
    return newhead;

2.2 代码实现

struct Node* copyRandomList(struct Node* head) {
	struct Node* cur=head;
    while(cur)
    {
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
        copy->next=cur->next;
        cur->next=copy;

        cur=copy->next;
    }

    cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;
        }
       cur=copy->next;  
    }

    struct Node* newhead=NULL,*tail=NULL;
    cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;
        if(tail==NULL)
        {
            newhead=tail=copy;
        }
        else
        {
            tail->next=copy;
            tail=tail->next;
        }
        cur->next=next;
        cur=next;
    }
    return newhead;
}

在这里插入图片描述
有问题请指出,大家一起进步!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

个人网站制作 Part 7 添加用户认证和数据库集成 | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 用户认证与数据库集成&#x1f528;添加用户认证&#x1f527;步骤 1: 使用Passport.js &#x1f528;集成数据库&#x1f527;步骤 2: 使用MongoDB和Mongoose &#x1f…

48 分布式id的生成策略

1.UUID 1.UUID (Universally Unique Identifier)&#xff0c;通用唯一识别码。UUID是基于当前时间、计数器&#xff08;counter&#xff09;和硬件标识&#xff08;通常为无线网卡的MAC地址&#xff09;等数据计算生成的。UUID由以下几部分的组合&#xff1a; 1.当前日期和时…

Apache Solr <= 8.8.1任意文件读取漏洞复现CVE-2019-17558

一、环境准备 搭建环境vulhub&#xff0c;需要提前安装docker环境 docker安装&#xff1a;docker--安装docker-ce-CSDN博客 vulhub地址&#xff1a;https://github.com/vulhub/vulhub #创建靶场环境 mkdir /opt/vulhub cd /opt/vulhub git https://github.com/vulhub/vulhu…

<软考高项备考>《论文专题 - 71 风险管理(3)》

3 过程2-识别风险 3.1 问题 4W1H过程做什么是识别单个项目风险以及整体项目风险的来源&#xff0c;并记录风险特征的过程。作用:1、记录现有的单个项目风险&#xff0c;以及整体项目风险的来源:2、汇总相关信息&#xff0c;以便项目团队能够恰当地应对已识别的风险。为什么做…

编译原理1.3习题 程序设计语言的发展历程

图源&#xff1a;文心一言 编译原理习题整理~&#x1f95d;&#x1f95d; 作为初学者的我&#xff0c;这些习题主要用于自我巩固。由于是自学&#xff0c;答案难免有误&#xff0c;非常欢迎各位小伙伴指正与讨论&#xff01;&#x1f44f;&#x1f4a1; 第1版&#xff1a;自…

【Java SE语法篇】11.异常

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1. 异常的概念和体系结构1.1 异常的概念1.2 异常体系…

企业微信开发:自建应用:access_token

access_token 过期后接口响应 access_token 已经过期&#xff08;2小时&#xff09;后&#xff0c;调用接口的响应&#xff1b;本文中以发送消息接口为例&#xff0c;说明接口响应的情况。 官方开发文档链接&#xff1a;获取access_token access_token 过期后调用接口 响应体 …

大模型学习与实践笔记(六)

一、finetune 简介 两种微调模式&#xff1a;增量预训练 与指令跟随 1.增量预训练 2.指令微调 二、LoRA 与 QLoRA 介绍 三、XTuner 介绍 四、低显存玩转LLM的方法

ASP.NET Core 的 Web Api 实现限流 中间件

Microsoft.AspNetCore.RateLimiting 中间件提供速率限制&#xff08;限流&#xff09;中间件。 它是.NET 7 以上版本才支持的中间件&#xff0c;刚看了一下&#xff0c;确实挺好用&#xff0c;下面给大家简单介绍一下&#xff1a; RateLimiterOptionsExtensions 类提供下列用…

【jupyter添加虚拟环境内核(pytorch、tensorflow)- 实操可行】

jupyter添加虚拟环境内核&#xff08;pytorch、tensorflow&#xff09;- 实操可行 1、查看当前状态(winR&#xff0c;cmd进入之后)2、激活虚拟环境并进入3、安装ipykernel5、完整步骤代码总结6、进入jupyter 添加pytorch、tensorflow内核操作相同&#xff0c;以下内容默认已经安…

Python - 深夜数据结构与算法之 Sort

目录 一.引言 二.排序简介 1.排序类型 2.时间复杂度 3.初级排序 4.高级排序 A.快速排序 B.归并排序 C.堆排序 5.特殊排序 三.经典算法实战 1.Quick-Sort 2.Merge-Sort 3.Heap-Sort 4.Relative-Sort-Array [1122] 5.Valid-anagram [242] 6.Merge-Intervals […

idea设置编辑器背景颜色

文章目录 一、Ided常用工具栏显示二、更改idea主题设置三、设置代码编辑器背景颜色为豆沙绿四、设置新项目 默认Jdk配置、maven配置1、settings for new projects2、structre for new projects 五、修改代码中注释的字体颜色六、设置编辑器字体大小七、文件编码的设置(可以设置…

leetcode-344. 反转字符串、9. 回文数

题目1&#xff1a; 解题方法 直接用reverse()即可 代码&#xff1a; class Solution(object):def reverseString(self, s):""":type s: List[str]:rtype: None Do not return anything, modify s in-place instead."""return s.reverse()如果不…

翻译: Pyenv管理Python版本从入门到精通二

Pyenv系列&#xff1a; 翻译: Pyenv管理Python版本从入门到精通一 1. 高级 Pyenv 用法 1.1 在 pyenv-virtualenv 中使用虚拟环境 可以使用 pyenv-virtualenv 扩展 Pyenv 来管理虚拟环境。这是隔离项目环境并有效管理其依赖项的好方法。以下是使用 pyenv-virtualenv 创建虚…

C# 面向切面编程之AspectCore实践(二)

写在前面 在上一篇中对AspectCore进行了初步的了解&#xff0c;用于拦截的属性加在了具体类的方法上。 C# 面向切面编程之AspectCore初探 这一篇验证一下把拦截属性加在接口上&#xff0c;这样实现该接口的类中所对应的方法都会被拦截到&#xff1b;另外示例中还尝试对方法的…

如何从命令行运行testng.xml?

目录 创建一个新的java项目并从命令行运行testng.xml 使用命令行运行XML文件 从命令行运行现有maven项目的XML文件 在这篇文章中&#xff0c;我们将使用命令行运行testng.xml。有多种场景需要使用命令行工具运行testng.xml。也许您已经创建了一个maven项目&#xff0c;现在想…

【VTKExamples::PolyData】第三期 DecimatePolylineDeleteCell

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例 DecimatePolyline折线抽取和 DeleteCell样例,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. DecimatePo…

YOLOv8改进 | 主干篇 | 低照度增强网络PE-YOLO改进主干(改进暗光条件下的物体检测模型)

一、本文介绍 本文给大家带来的改进机制是低照度图像增强网络PE-YOLO中的PENet,PENet通过拉普拉斯金字塔将图像分解成多个分辨率的组件,增强图像细节和低频信息。它包括一个细节处理模块(DPM),用于通过上下文分支和边缘分支增强图像细节,以及一个低频增强滤波器(LEF),…

C语言经典算法之顺序查找算法

目录 前言 A.建议 B.简介 一 代码实现 二 算法时空复杂度 A.时间复杂度&#xff1a; B.空间复杂度&#xff1a; 三 优点和缺点 A.优点&#xff1a; B.缺点&#xff1a; 四 现实中的应用 前言 A.建议 1.学习算法最重要的是理解算法的每一步&#xff0c;而不是记住算…

steam搬砖项目风险在哪里?这几点一定要记牢

你可能已经听说过Steam搬砖项目&#xff0c;这是一个通过在Steam平台充值美元&#xff0c;购买道具&#xff0c;然后将这些道具转移到BUFF平台进行交易&#xff0c;从而获取利润的方式。这个项目的操作方法主要是利用一些渠道和经验技巧&#xff0c;购买低价道具&#xff0c;然…