环链表相关的题目和算法[LeetCode]
这篇文章讨论一下与链表的环相关的题目,我目前遇到的一共有3种题目。
1.判断一个链表是否有环(LeetCode相关题目:https://leetcode.com/problems/linked-list-cycle/description/)
设置两个指针,初始值都指向头,一快一慢,slow每次前进一步,fast每次前进两步,假如链表存在环,两个指针必定会相遇。假如fast走到尾部,则为无环链表。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *fast = head;
ListNode *slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (slow == fast) {
return true;
}
}
return false;
}
};
2.判断一个有环链表中环的位置(LeetCode相关题目:https://leetcode.com/problems/linked-list-cycle-ii/description/)
也是利用到一快一慢的两个指针,借用网上一个图:

两个指针顺时针走动,fast一次走两步,slow一次走一步,假设两个指针第一次在Z相遇,slow走过的距离为a+b,fast走过的距离为a+b+c+b,2(a + b) == a + b + c + b,得出a == c,因此此时将fast指针放回起点,将两次走一步改为一次走一步。此时,fast和slow同时开始走,由于他们的路程和速度都一样,因此他们会在环的起点相遇。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while (true) {
if (fast == NULL || fast->next == NULL) return NULL;
else {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) break;
}
}
fast = head;
while (fast != slow) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
3.求两个链表的交点(LeetCode相关题目:https://leetcode.com/problems/intersection-of-two-linked-lists/description/)
尽管看上去和链表的环没啥关系,但是这个题目可以用这种方法来做。我们可以先将其中一个环的头尾相连,然后按照上一题的做法,就可以找到交点的位置了。不过要记得将一切复原,也就是将环解开。
代码如下:
/**
* 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) {
if (headA == NULL || headB == NULL) return NULL;
ListNode *copyA = headA;
ListNode *copyB = headB;
while (headA->next != NULL) {
headA = headA->next;
}
ListNode *recover = headA;
headA->next = copyA;
ListNode *fast = headB;
ListNode *slow = headB;
while (true) {
if (!fast || !fast->next) {
recover->next = NULL;
headA = copyA;
headB = copyB;
return NULL;
}
fast = fast->next->next;
slow = slow->next;
if (fast == slow) break;
}
fast = headB;
while (fast != slow) {
slow = slow->next;
fast = fast->next;
}
recover->next = NULL;
headA = copyA;
headB = copyB;
return slow;
}
};
4.其他的。。。
我能想到的其他题目类型:
求环的长度:在2的前提下,从环的起点开始,一个指针不动,一个指针走,统计走的长度,两个指针重新相遇时的长度就是环的长度
将环解开:原理其实一样
因此,这类题目的关键是利用一快一慢两个指针,然后要懂得找出环的起点的方法,其他变形的问题也就迎刃而解了。
环链表相关的题目和算法[LeetCode]的更多相关文章
- 算法<初级> - 第二章 队列、栈、哈希表相关问题
算法 - 第二章 数据结构 题目一 用数组实现大小固定的队列和栈(一面题) 数组实现大小固定栈 /*** * size是对头索引(initSize是固定大小) 也是当前栈大小 * size=下个进队i ...
- 前端与算法 leetcode 26. 删除排序数组中的重复项
目录 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 26. 删除排序数 ...
- 前端与算法 leetcode 350. 两个数组的交集 II
目录 # 前端与算法 leetcode 350. 两个数组的交集 II 题目描述 概要 提示 解析 解法一:哈希表 解法二:双指针 解法三:暴力法 算法 # 前端与算法 leetcode 350. 两 ...
- 前端与算法 leetcode 283. 移动零
目录 # 前端与算法 leetcode 283. 移动零 题目描述 概要 提示 解析 解法一:暴力法 解法二:双指针法 算法 传入[0,1,0,3,12]的运行结果 执行结果 GitHub仓库 # 前 ...
- 前端与算法 leetcode 1. 两数之和
目录 # 前端与算法 leetcode 1. 两数之和 题目描述 概要 提示 解析 解法一:暴力法 解法二:HashMap法 算法 传入[1, 2], [11, 1, 2, 3, 2]的运行结果 执行 ...
- 前端与算法 leetcode 48. 旋转图像
目录 # 前端与算法 leetcode 48. 旋转图像 题目描述 概要 提示 解析 解法一:转置加翻转 解法二:在单次循环中旋转 4 个矩形 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...
- 前端与算法 leetcode 7. 整数反转
目录 # 前端与算法 leetcode 7. 整数反转 题目描述 概要 提示 解析 解法 算法 传入测试用例的运行结果 执行结果 GitHub仓库 # 前端与算法 leetcode 7. 整数反转 题 ...
- 前端与算法 leetcode 8. 字符串转换整数 (atoi)
目录 # 前端与算法 leetcode 8. 字符串转换整数 (atoi) 题目描述 概要 提示 解析 解法一:正则 解法二:api 解法二:手搓一个api 算法 传入测试用例的运行结果 执行结果 G ...
- 前端与算法 leetcode 387. 字符串中的第一个唯一字符
目录 # 前端与算法 leetcode 387. 字符串中的第一个唯一字符 题目描述 概要 提示 解析 解法一:双循环 解法二:Set法单循环 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...
随机推荐
- 使用sshkey的方式访问gitlab
在使用jenkins创建jobs的时候配置git为ssh访问的方式报错 记录错误信息 Failed to connect to repository : Command "/usr/bin/ ...
- thinphp原生异步分页
异步分页: $sql="............"; $result=$m->query($sql); $count =count($result); $page ...
- Hi3518EV200平台ADC多通道采样
Hi3518EV200平台ADC多通道采样流程 Hi3518EV200 ADC 本文针对Hi3518EV200平台处理器,通过ADC单次采样方式,实现对多通道(1~4通道)ADC进行采样控制.本文仅仅 ...
- 【Java框架型项目从入门到装逼】第三节 - 如何用Tomcat发布web项目?
啥叫Tomcat?有道词典是这么说的. 这个我们姑且不管,实际上呢,Tomcat是一种Web服务器,我们自己做好了一个Web项目,就可以通过Tomcat来发布.服务器呢,又分为硬件服务器和软件服务器. ...
- Android App插件式换肤实现方案
背景 目前很多app都具有换肤功能,用户可以根据需要切换不同的皮肤,为使我们的App支持换肤功能,给用户提供更好的体验,在这里对换肤原理进行研究总结,并选择一个合适的换肤解决方案. 换肤介绍 App换 ...
- 浅析php命名空间
介绍 印象中只有java代码才会用到一大堆的import,当初看到后一脸懵逼并对php心生自豪:还是我大php牛逼够简洁,殊不知php也有命名空间这一说,这些年用的越来越多.那么,为什么要搞那么麻烦呢 ...
- 51Nod--1051最大子矩阵和(DP入门)
分析: 我们已经解决了一维的问题(基础篇中的最大子段和问题),现在变成二维了,我们看看能不能把这个问题转化为一维的问题.最后子矩阵一定是在某两行之间的.假设我们认为子矩阵在第i行和第j列之间,我们如何 ...
- php综合运用技术
五.PHP综合应用 1.写出下列服务的用途和默认端口(新浪网技术部) ftp.ssh.http.telnet.https ftp:File Transfer Protocol,文件传输协议,是应用层的 ...
- 关于AJAX使用中出现中文乱码的问题
自己初学AJAX,遇到一个棘手的bug就是xmlHttp.open("get",url,false);url里面有中文,结果出现乱码.不过最后在百度,和诸位博主的帮助下,成功解决了 ...
- 进程与进程描写叙述符(task_struct)
一. 进程 进程(Process) 计算机中的程序关于某数据集合上的一次执行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...