这篇文章讨论一下与链表的环相关的题目,我目前遇到的一共有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]的更多相关文章

  1. 算法<初级> - 第二章 队列、栈、哈希表相关问题

    算法 - 第二章 数据结构 题目一 用数组实现大小固定的队列和栈(一面题) 数组实现大小固定栈 /*** * size是对头索引(initSize是固定大小) 也是当前栈大小 * size=下个进队i ...

  2. 前端与算法 leetcode 26. 删除排序数组中的重复项

    目录 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 26. 删除排序数 ...

  3. 前端与算法 leetcode 350. 两个数组的交集 II

    目录 # 前端与算法 leetcode 350. 两个数组的交集 II 题目描述 概要 提示 解析 解法一:哈希表 解法二:双指针 解法三:暴力法 算法 # 前端与算法 leetcode 350. 两 ...

  4. 前端与算法 leetcode 283. 移动零

    目录 # 前端与算法 leetcode 283. 移动零 题目描述 概要 提示 解析 解法一:暴力法 解法二:双指针法 算法 传入[0,1,0,3,12]的运行结果 执行结果 GitHub仓库 # 前 ...

  5. 前端与算法 leetcode 1. 两数之和

    目录 # 前端与算法 leetcode 1. 两数之和 题目描述 概要 提示 解析 解法一:暴力法 解法二:HashMap法 算法 传入[1, 2], [11, 1, 2, 3, 2]的运行结果 执行 ...

  6. 前端与算法 leetcode 48. 旋转图像

    目录 # 前端与算法 leetcode 48. 旋转图像 题目描述 概要 提示 解析 解法一:转置加翻转 解法二:在单次循环中旋转 4 个矩形 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...

  7. 前端与算法 leetcode 7. 整数反转

    目录 # 前端与算法 leetcode 7. 整数反转 题目描述 概要 提示 解析 解法 算法 传入测试用例的运行结果 执行结果 GitHub仓库 # 前端与算法 leetcode 7. 整数反转 题 ...

  8. 前端与算法 leetcode 8. 字符串转换整数 (atoi)

    目录 # 前端与算法 leetcode 8. 字符串转换整数 (atoi) 题目描述 概要 提示 解析 解法一:正则 解法二:api 解法二:手搓一个api 算法 传入测试用例的运行结果 执行结果 G ...

  9. 前端与算法 leetcode 387. 字符串中的第一个唯一字符

    目录 # 前端与算法 leetcode 387. 字符串中的第一个唯一字符 题目描述 概要 提示 解析 解法一:双循环 解法二:Set法单循环 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...

随机推荐

  1. Loadrunner web_url函数学习(转贴)

    http://blog.csdn.net/dfbrt56/article/details/3291461 ----------------------------------------------- ...

  2. 安卓Html标签,创意工具类

    之前开发项目中,遇到了在Textview中使用Html标签的情形,由于在代码中使用字符串,Android Studio上一堆的黄色警告,而且对于过时的Html.fromHtml,拿它一点办法也没有. ...

  3. MatlabR2015b用了一段时间之后需要重新激活

    问题描述:MatlabR2015b安装成功,用了一段时间之后需要重新激活,按照http://www.cr173.com/soft/490645.html教程,无法激活成功,卸载重新安装也不行. 解决方 ...

  4. Android 在通知栏实现计时功能

    Notification是APP 向系统发出通知时,它将先以图标的形式显示在通知栏中.用户可以下拉通知栏查看通知的详细信息.我们可以在通知栏实现自定义的效果,也可以结合service和BroadCas ...

  5. C# 通过url地址获取页面内容

    using System.Net; using System.IO; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(" ...

  6. Qt---Xml文件解析

    本文我们通过一个读取Xml文件的小例子来学习QXmlStreamReader. Xml 简介 Xml的全称是可扩展标记语言(EXtensible Markup Language),同HTML一样是一种 ...

  7. canvas画一个时钟

    效果图如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. nignx 测试配置文件

    nginx -t nginx: the configuration file /usr/local/nginx-1.2.9/conf/nginx.conf syntax is ok nginx: co ...

  9. 机器学习笔记1 - Hello World In Machine Learning

    前言 Alpha Go在16年以4:1的战绩打败了李世石,17年又以3:0的战绩战胜了中国围棋天才柯洁,这真是科技界振奋人心的进步.伴随着媒体的大量宣传,此事变成了妇孺皆知的大事件.大家又开始激烈的讨 ...

  10. Replace Pioneer

    Replace Pioneer(官网:http://www.mind-pioneer.com)是一款专业的文本批量处理软件.仅仅要给定不论什么纯文本文件或文件列表.仅仅要准确设置转换规则.就能得到不论 ...