142. 环形链表II
知识点:链表、快慢指针
时间:2020年10月10日
题目链接:https://leetcode-cn.com/problems/linked-list-cycle-ii/
题目
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
示例1
输入:
head = [3,2,0,-4], pos = 1
输出:
返回索引为 1 的链表节点
解释:
链表中有一个环,其尾部连接到第二个节点。
示例2
输入:
head = [1,2], pos = 0
输出:
返回索引为 0 的链表节点
解释:
链表中有一个环,其尾部连接到第一个节点。
示例3
输入:
head = [1], pos = -1
输出:
返回null
解释:
链表中没有环
提示:
- 链表中节点的数目范围是 [0, 104]
- -105 <= Node.val <= 105
- pos 为 -1 或者链表中的一个 有效索引 。
思路
方法1:
- 遍历寻找,每次保存一下节点,按照链表顺序遍历,如果出现之前有的节点,则有环路
方法2:
- 快慢指针,如果有环,快指针会追上慢指针
- 假设走入环之前的距离为a,入环节点到快慢指针相遇的距离为b,快慢指针相遇节点到入环节点的距离为c,
- 快指针走的距离为a+n(b+c)+b
- 慢指针走的距离为a+b
- 快指针走的速度是慢指针的两倍 a+n(b+c)+b = 2a+2b
- a = c+(n-1)(b+c)
- 假设n=1,a=c,慢指针走距离c到达入环节点,我们这里引入指针tmp=head,和慢指针一起运动,他们相遇的时候就是入环点
代码
#include <stdio.h>
#include <stdio.h>
#include <iostream>
#include <unordered_set>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
/*遍历节点
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode*> s;
while(head){
if(s.count(head)){
return head;
}
s.insert(head);
head = head->next;
}
return nullptr;
}
};
*/
/*快慢指针
1. 假设走入环之前的距离为a,入环节点到快慢指针相遇的距离为b,快慢指针相遇节点到入环节点的距离为c,
2. 快指针走的距离为a+n(b+c)+b
3. 慢指针走的距离为a+b
4. 快指针走的速度是慢指针的两倍 a+n(b+c)+b = 2a+2b
5. a = c+(n-1)(b+c)
6. 假设n=1,a=c,慢节点走c距离到达入环节点,我们这里引入指针tmp=head,和慢节点一起运动,他们相遇的时候就是入环点
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head== nullptr || head->next== nullptr){return nullptr;}
ListNode* slow = head;
ListNode* fast = head->next;
while(fast != nullptr){
slow = slow->next;
if(fast->next == nullptr) {
return nullptr;
}
fast = fast->next->next;
if(slow == fast){
ListNode *tmp = head;
while (tmp != slow) {
tmp = tmp->next;
slow = slow->next;
}
return tmp;
}
}
return nullptr;
}
};
int main()
{
ListNode head(1);ListNode node1(1);ListNode node2(1);
head.next = &node1; node1.next = &node2;
node2.next = &head;
Solution s;
cout<<s.detectCycle(&head)<<endl;
return 0;
}
今天也是爱zz的一天哦!