DS:顺序表、单链表的相关OJ题训练(2)

欢迎各位来到 Harper.Lee 的学习世界!

博主主页传送门:Harper.Lee的博客主页

想要一起进步的uu欢迎来后台找我哦!


一、力扣--141. 环形链表

        题目描述:给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回 true 。 否则,返回 false 。

        常见环形链表有以下几种:(环形链表不清楚最后一个节点即尾节点在哪里的)。

        常见的一种判断链表是否带环的错误方法:某节点的next指针和遍历的pcur的next指针相同,就认为该链表带环。这是错误的!!! 因为我们不知道遍历的pcur指针是否进环,他可能在环外,也可能在环内。

最好的办法就是使用快慢指针追击:慢指针slow一次走一步,快指针fast一次走两步。当

bool hasCycle(struct ListNode *head) {struct ListNode* slow = head,*fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;//两个nextif(slow == fast)return true;}return false;
}

Q1:为什么一定会相遇?

        假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。此时,两个指针每移动一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情况,因此:在满指针走到一圈之前,快指针肯定是可以追上慢指针的,即相遇。

Q2:快指针一次走3步,走4步,...n步行吗?

根据分析可知,快慢指针的追击问题不在于两者一次走多少步,而在于快慢指针之间的速度差

分析过程图片:

Q3:有没有可能会错过,永远追不上?

分析过程图片: 

       所以答案是:一定会追上,一定能追上!

二、力扣--142. 环形链表 II

 题目描述:给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

三、力扣---02.02. 返回倒数第 k 个节点

思路一:创建一个新数组,在数组中寻找相应的数据,返回数据对应的下标。(空间复杂度高了)

思路二:第一遍遍历得出节点个数(n),如果要求找倒数第k个节点,就去找正数第n-k+1个节点,并返回该节点的值。

思路三(在思路二的基础上要求空间复杂度O(1),也就是只能遍历链表一遍):快慢指针法。fast先走k步,拉开差距,然后两个指针再同时移动。注意单链表是不能倒着走的。可以加一个判断:k小于等于链表长度。

int kthToLast(struct ListNode* head, int k){struct ListNode* fast = head,*slow = head;//均是从头节点开始///快指针先走k步(或者k-1步)while(k--){fast = fast->next;}while(fast)//快慢指针同时走,快指针先走到头{slow = slow->next;fast = fast->next;}return slow->val;
}

四、牛客--OR36 链表的回文结构

        题目描述:对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。如:1->2->2->1,返回true。

单链表有奇数个和偶数个两种情况:1、先查找中间节点;2、后半段逆置。

代码如下:

/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
//查找中间节点 
struct ListNode* middleNode(struct ListNode* head)
{struct ListNode* slow =head,*fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next;}return slow;
}struct ListNode* reverseList(struct ListNode* head)
{struct ListNode* cur = head;struct ListNode* newhead = NULL;while (cur){struct ListNode* next =cur->next;//头插cur->next=newhead;newhead = cur;cur = next;}return newhead;
}bool chkPalindrome(ListNode* A) {struct ListNode* mid = middleNode(A);//查找中间节点struct ListNode* rmid = reverseList(mid);//逆置后半段while(rmid && A)//有一个为空,就结束了,则都不为空进入循环{if(rmid->val!=A->val)return false;rmid = rmid->next;}return true;}
};

五、力扣--160. 相交链表

        题目描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交

 

         链表的相交的形式:不是X字型,而是Y字型, 因为单链表的一个节点只能有一个next指针。

         思路一:A链表逐个结点与B链表比较,如果存在相等,则就是相交结点(注:要比较指针而不能比较值,因为值是可以重复的)。
        具体过程分析:1. 判断两个链表是否相交:判断两个链表的尾指针是否相等,相等则两个链表相交,注意用地址来判断而不是值。2. 若相交,找出第一个交点:用暴力求解,链表A的节点依次和链表B的所有节点比较一遍(比较地址,而不是值),如果链表A的某个节点和链表B相等,则这个节点就是交点。 最坏情况:不相交,时间复杂度:O(m*n)(两个链表的长度)。

        思路二:长的链表往前走长度差到短链表开头,再同时走,直到相等就是相交点。    

        最坏的情况:最后一个才遇到交点。F(n)=3*N,时间复杂度O(N)。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
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;}//尾节点不相等就是相交if(curA != curB){return NULL;}//长链表先走差距步,两个链表再同时走,第一个相等就是交点//假设法:让逻辑更加简单int gap = abs(lenA - lenB);struct ListNode* longList = headA,*shortList = headB;if(lenB > lenA){longList =headB;shortList= headA;}while(gap--){longList = longList->next;}while(longList != shortList){longList = longList->next;shortList = shortList->next;}return shortList;
}


创作不易,喜欢的uu三连支持一下叭! 

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

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

相关文章

java数据结构之数组系统了解

1.数组介绍 数组就是一个存储数据的容器,容器的长度固定、存储元素的数据类型固定。 跟变量加以区分:变量也可以存储数据,但是只能存一个值。当要存的数据比较多的时候,用变量就不方便了。我们就可以使用数组来存储。 1.1数组…

嫁接打印的技术要点

所谓嫁接打印,是一种增减材混合制造的方式。它将已成形的模具零件当作基座,在此基础上“生长”出打印的零件。其中基座通常采用传统加工方式制造,而打印部分则使用专用的金属粉末,通过 3D 打印技术成型。 嫁接打印之所以备受欢迎&…

安全 | 开源入侵防御系统 Snort

目录 Snort 概要 入侵预防系统模式 数据包记录器和嗅探器模式 网络安全学习路线 (2024最新整理) 学习资料的推荐 1.视频教程 2.SRC技术文档&PDF书籍 3.大厂面试题 特别声明: Snort 概要 Snort 概要 是世界上最重要的开源入…

Python语言基础学习(上)

目录 一、常量和表达式 二、变量和类型 2.1 认识变量 2.2 定义变量 2.3 变量类型 1、整数 int 2、浮点数(小数)float 3、字符串 str 4、布尔类型 2.4 类型转换 三、注释 3.1 单行注释 3.2 文档注释(或者多行注释) …

MySQL 通过 systemd 启动时 hang 住了……

mysqld:哥,我起不来了…… 作者:贲绍华,爱可生研发中心工程师,负责项目的需求与维护工作。其他身份:柯基铲屎官。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编…

谈基于ATTCK框架的攻击链溯源

引言 网络安全在当今数字化时代变得尤为关键,而MITRE公司开发的ATT&CK框架则成为了安全专业人员的重要工具。ATT&CK是一种广泛使用的攻击行为分类和描述框架。其目的在于提供一个共同的语言,使安全专业人员能够更好地理解攻击者的行为和目标&…

【NPM】Nginx Proxy Manager 一键申请 SSL 证书,自动续期,解决阿里云SSL免费证书每3个月失效问题

文章目录 1、NPM 简介2、实战Step 1:环境搭建 也可以看作者安装笔记 Step 2:创建容器 2.1 在系统任意位置创建一个文件夹,此文档以~/nginx-proxy-manager为例。2.2 创建docker-compose.yaml2.3 启动NPM服务 Step 3:配置反向代理3…

PyTorch 图像篇

计算机视觉技术是一门包括计算机科学与工程、神经生理学、物理学、信号处理、认知科学、应用数学与统计等多学科的综合性科学技术, 是人工智能的一个重要分支, 目前在智能安防、自动驾驶汽车、医疗保健、生成制造等领域具有重要的应用价值。 计算机视觉…

网络编程--tcp三次握手四次挥手

1、三次握手 (1)三次握手的详述 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。…

图片转图标(ICO)的工具软件

目前常用的ICO转换方式大多都是网页在线转换,没网就无法使用了。自己编写了一款小软件,可以将各种格式图片转为ICO图标。 目前支持PNG,BMP,JPG,JPEG,GIF等格式的图片转换成ICO,支持的尺寸有常用的16*16,24*24,32*32&am…

信息与未来2017真题笔记

T1. 龟兔赛跑 题目描述 兔子又来找乌龟赛跑啦!同样的错误兔子不会犯两次,所以兔子提出赛跑的时候,乌龟就觉得这场比赛很不公平。于是兔子进一步放宽了条件,表示他可以在比赛开始以后先睡 t t t 分钟再开始追乌龟。 乌龟这下没…

【mysql】主从同步时出错,如何恢复同步

mysql主从同步出错,这个时候从服务器会停止同步服务,等待人工恢复,此时有多种方法来解决。 一、查看状态 在从服务器,登陆mysql,查询从服务器的状态: 从服务器mysql> show slave status\G 图1 可以看…