链表OJ刷题(二)

news2024/9/22 5:37:46

制作不易,三连支持一下呗!!!

文章目录

  • 前言
  • 一、链表的回文结构
  • 二、相交链表
  • 三、链表中倒数第k个节点
  • 四、环形链表Ⅰ和Ⅱ
  • 总结


前言


一、链表的回文结构

链表的回文结构_牛客题霸_牛客网

这里我们需要先了解一下什么叫做回文:从前向后看与从后向前看的结果是一样的,我们就称为回文结构!!!

思路: 这道题目是我们之前链表OJ(一)中两道经典题目的结合------查找中间节点与链表的逆置。

我们可以先找到链表的中间节点(如果链表节点个数为偶数,有两个中间节点,我们选取靠后的那一个),然后将链表的中间节点以后的节点全部逆置。最后循环遍历原链表的前半部分和逆置得到的后半部分是否相同,如果相同就是回文结构,反之就不是。

 我们只需要将这两个步骤分别实现成函数来调用即可

代码实现:

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
typedef struct ListNode ListNode;
//查找中间节点
struct ListNode* middleNode(struct ListNode* head) {
    ListNode* pfast,*pslow;
    pfast=pslow=head;
    while(pfast&&pfast->next)
    {
         pfast=pfast->next->next;
         pslow=pslow->next;
    }
    return pslow;
}
//逆置所传链表
struct ListNode* reverseList(struct ListNode* head) {
    if(!head)
    {
        return head;
    }
    ListNode*prev,*pcur,*next;
    prev=NULL;
    pcur=head;
    next=head->next;
    while(pcur)
    {
        pcur->next=prev;
        prev=pcur;
        pcur=next;
        if(next)
        next=next->next;
    }
    return prev;
}
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        if(!A)
        return true;
     ListNode* mid=middleNode(A);
     mid= reverseList(mid);
     //循环遍历两个链表,进行比较
     while(mid)
     {
        if(A->val!=mid->val)
        return false;
        mid=mid->next;
        A=A->next;
     }
     return true;
    }
};

二、相交链表

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 思路一:计算两个链表的长度

 步骤:

1.先判断是否相交:

如果两个链表的尾节点相同则一定是相交的,如果连尾节点都不同,则一定不相交。

2.找到相交的起始节点:

先分别通过循环遍历的方式计算出两个链表的长度lenA和lenB,用gap来表示它们之间的差值,让长链表先遍历gap步,以保证此时链表的长度是相同的,最后循环遍历两个链表,如果出现链表A和链表B的节点是相同的,则表示这个节点就是我们要找的节点。

代码实现:

 typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    int lenA=0,lenB=0;
    ListNode* curA=headA,*curB=headB;
    //计算链表A的长度
    while(curA)
    {
        lenA++;
        curA=curA->next;
    }
    //计算链表B的长度
     while(curB)
    {
        lenB++;
        curB=curB->next;
    }
    //判断尾节点是否相同
    if(curA!=curB)
    {
    return NULL;
    }
    int gap=abs(lenA-lenB);
    ListNode* longlist=headA;
    ListNode* shortlist=headB;
    if(lenB>lenA)
    {
        longlist=headB;
        shortlist=headA;
    }
    //让长链表先走gap步
    while(gap--)
    {
        longlist=longlist->next;
    }
    //循环找相交起始节点
    while(longlist!=shortlist)
    {
        longlist=longlist->next;
        shortlist=shortlist->next;
    }
    return longlist;
}

思路二: 走相同的路,彼此一定会相遇

除了计算链表长度外,我们可以通过两个链表长度和相同的性质来解题

过程:遍历其中一个链表,当到末尾时跳到另一个链表继续遍历,直到再次到达末尾

1.如果链表不相交,则两个遍历指针同时指向NULL,返回NULL即可。

2.如果链表相交,因为两个遍历指针同时达到末尾,向前推理可知,两个指针一定会有同时指向相交的起始节点的时候。

3.如果两个链表等长,也会同时到达相交的起始节点。

代码实现:

这个思路实现起来就比较简洁,但是不容易想到!!! 

三、链表中倒数第k个节点 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路一:求出链表长度,确定所求节点是第几个节点

思路非常简单

代码实现:

思路二:双指针法

受链表的中间节点一题的启发,我们这里依旧可以使用快慢指针,只需要将快慢指针的距离控制在k,当快指针走到链表末尾时,慢指针正好到达所求节点。

代码实现:

四 、环形链表Ⅰ和Ⅱ

环形链表Ⅰ:

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

思路: 快慢指针法

定义一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步。如果此链表带环则,快慢两个指针一定会相遇,如果此链表不带环,则fast指针或fast->next最后一定会是NULL。

代码实现:

typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
    ListNode* fast=head,*slow=head;
    while(fast&&fast->next)//注意:顺序不能调换,否则可能会存在短路的情况
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        {
            return true;
        }
    }
    return false;
}

接下来我们从数学的角度解释为什么两个指针一定会相遇:

 

假设上图是一个带环链表 ,当slow也进环时,假设fast与环的入口之间的距离是X,环的长度是C

由于两个指针的速度差是1 ,总有一天fast指针会追上slow指针,并不会错过,并且此时slow指针一定还没有走够一圈(因为X<C),所以我们就证明了一个指针走两步,一个指针走一步一定可以追上!!!


同理 如果一个指针走三步,一个指针走一步,我们也可以用相同的思路来验证是否一定会追上:

答案是一定会。

假设slow进环时两个指针的位置如上图所示。 

一.假设此时两个指针的距离N为偶数,则因为每走一步两个指针的距离缩小2,那么在第一轮fast一定可以追上slow(并且此时slow并未转够一圈)!!!

二.如果N为奇数,则第一圈并不能追上,则两个指针的距离在经过第一轮追击之后会变为C-1(C为环的长度)。

1.如果C-1是偶数,则下一轮就一定可以追上。

2.如果C-1是奇数,则永远也追不上!!!

问题是:N为奇数和C-1是奇数是否可以同时成立呢?

我们假设未进环时slow走的距离是L,slow刚进环时slow和fast的距离是N,环的长度是C,fast已经转了x圈。

slow走的距离是:L

fast走的距离是:L+x*C+N

因为fast的速度是slow的3倍,则3L=L+x*C+N

推出:2L=x*C+N

2L一定是偶数,如果C-1和N同时为奇数,则x*C一定是偶数,x*C+N就一定是奇数,两边不可能相等,矛盾!!!

因此只要N为奇数时,fast一定可以在第二轮追击中追上slow

也就是说,不管如何,fast一定能够追上slow!!!

但是由于fast走两步,slow走一步写起来更简单,我们选择这种方法。


总结

环形链表的逻辑推理很重要!!!

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

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

相关文章

测开新手:pytest+requests+allure自动化测试接入Jenkins学习

最近在这整理知识&#xff0c;发现在pytest的知识文档缺少系统性&#xff0c;这里整理一下&#xff0c;方便后续回忆。 在python中&#xff0c;大家比较熟悉的两个框架是unittest和pytest&#xff1a; Unittest是Python标准库中自带的单元测试框架&#xff0c;Unittest有时候…

基于python+django+mysql在线点餐订餐外卖系统设计与实现 开题报告参考

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

排序(3)——直接选择排序

目录 直接选择排序 基本思想 整体思路&#xff08;升序&#xff09; 单趟 多趟 代码实现 特性总结 直接选择排序 基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的…

Python程序打包成exe可执行文件的常用方法

在Python中,您可以使用一些工具将您的Python程序打包成可执行文件(.exe)。以下是一些常用的工具: PyInstaller: PyInstaller是一个流行的工具,它可以将Python脚本打包成独立的可执行文件,支持Windows、Linux和Mac。您可以使用以下命令安装PyInstaller: pip install pyin…

Matlab:元胞自动机

元胞自动机是一种基于离散空间的动态系统&#xff0c;由许多简单单元按照某些规则进行相互作用和演化而形成的复杂结构。元胞自动机可以用于模拟物理、生物、社会等领域的现象&#xff0c;以及进行优化、图像处理、噪声生成等方面的应用。 例1&#xff1a;生命游戏 nextState…

每日一类:QLabel深入解析

QLabel是Qt中用于显示文本或图像的控件&#xff0c;属于Qt Widgets模块。它是展示静态内容的理想选择&#xff0c;支持富文本格式&#xff0c;使得文本可以包含不同的字体、颜色和链接。QLabel也可以用来显示图像&#xff0c;包括动态图像。此外&#xff0c;它还支持文本和图像…

【硬件相关】IB网/以太网基础介绍及部署实践

文章目录 一、前言1、Infiniband网络1.1、网络类型1.2、网络拓扑1.3、硬件设备1.3.1、网卡1.3.2、连接线缆a、光模块b、线缆 1.3.4、交换机 2、Ethernet网络 二、部署实践&#xff08;以太网&#xff09;1、Intel E810-XXVDA21.1、网卡信息1.2、检查命令1.2、驱动编译 2、Mella…

MySQL进阶:全局锁、表级锁、行级锁总结

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;MySQL进阶&#xff1a;MySQL事务、并发事务问题及隔离级别 &#x1f4da;订阅专栏&#xff1a;MySQL进阶 希望文章对你们有所帮助…

如何根据玩家数量和游戏需求选择最合适的服务器配置?

根据玩家数量和游戏需求选择最合适的服务器配置&#xff0c;首先需要考虑游戏的类型、玩家数量、预计的在线时间以及对内存和CPU性能的需求综合考虑。对于大型多人在线游戏&#xff0c;如MMORPG或MOBA等&#xff0c;由于需要更多的CPU核心数来支持更复杂的游戏逻辑和处理大量数…

【Spring Boot 3】的安全防线:整合 【Spring Security 6】

简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与Sp…

Python中几个必须知道的函数

Python中自带了几个比较有意思的函数&#xff0c;一般在面试或者笔试基础的时候会问到&#xff0c;其中3个就是map、filter、reduce函数。 1.map(function, iterable) 它第一个要传的元素是函数名或lambda匿名函数表达式&#xff0c;第二个元素传入可迭代对象。 array [1,2,…

【饮食】日常零食 保健食品分类(附食品营养成分表与执行标准,Coursera营养学课程笔记)

程序员生活指南之 【饮食】日常零食 & 保健食品分类和推荐&#xff08;附食品营养成分表与执行标准&#xff09; 文章目录 一、保健食品1、什么是保健食品&#xff1f;2、常见保健食品分类3、常见保健食品推荐 二、日常零食&#xff08;食品营养成分表与执行标准&#xff0…

详解JavaScript的函数

详解 JavaScript 的函数 函数的语法格式 创建函数/函数声明/函数定义 function 函数名(形参列表) { 函数体 return 返回值; // return 语句可省略 } 函数调用 函数名(实参列表) // 不考虑返回值 返回值 函数名(实参列表) // 考虑返回值 示例代码 //定义的没有参数列表&am…

【C语言】sizeof和strlen的比较

1. sizeof和strlen的对比 1.1 sizeof 在学习操作符的时候&#xff0c;我们学习了 sizeof &#xff0c; sizeof 是一个单目操作符&#xff0c; 绝对不是函数&#xff01;&#xff01;&#xff01;sizeof 计算变量所占内存内存空间⼤⼩的&#xff0c;单位是字节。 如果操作数…

three.js 点乘判断平行向量方向异同

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs"></div><div>判断的前提是两个向量平行<el-button click"judge"…

2025张宇考研数学,百度网盘视频课+36讲PDF讲义+真题

张宇老师的课属于幽默生动&#xff0c;会让一个文科生爱上数学&#xff0c;但是有的同学不知道在哪看&#xff0c;可以看一下&#xff1a;2025张宇考研数学全程网盘 docs.qq.com/doc/DTmtOa0Fzc0V3WElI 可以粘贴在浏览器 张宇30讲作为一本基础讲义&#xff1a;和教材…

6、wuzhicms代码审计

wuzhicms代码审计 前言 安装环境配置 服务器要求 Web服务器: apache/nginx/iis PHP环境要求:支持php5.2、php5.3、php5.4、php5.5、php5.6、php7.1 (推荐使用5.4或更高版本!) 数据库要求: Mysql5www/install文件夹即可进入安装页面 审计开始 首页文件index.php&#xff0c…

latex使用Bibtex添加参考文献指南(TeXstudio)

目录 参考链接 Bibtex 使用方法 编译方法 参考链接 https://www.cnblogs.com/whyaza/p/11803493.html &#xff08;Latex&#xff09;Latex TeXstudio Bibtex 使用指南 - 简书 Latex-bibtex使用方法-CSDN博客 Latex插入参考文献的两种方法—自动与手动_latex 参考文献-…

免费下载全网视频系列:一键下载央视视频

之前分享过全网视频下载工具下载视频不求人&#xff0c;免费下载全网视频&#xff0c;今天再分享几个下载央视视频的工具。 第一个是央视频4k下载器&#xff0c;比如下载这个视频https://www.yangshipin.cn/#/video/home?vidv0000313oqb&#xff0c;打开工具在命令行输入 v00…

Ubuntu将c++编译成.so文件并测试

一、准备cpp和h文件 创建test.cpp 在cpp中定义相加的函数funcAdd&#xff0c;给出函数的细节代码 #include <iostream> using namespace std;int funcAdd(int x, int y) {return xy; }创建test.h 在h中声明定义的函数&#xff0c;不需要任何细节 #ifndef __TEST__ #…