题目:
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
这一题,最粗暴的解法,就是存在hash表里,依次遍历检查是否存在过;
很明细,需要额外的空间复杂度O(n);
其时间复杂度为O(n);因为只要遍历一边链表即可,查询是在O(1)范围之内的。
class Solution {
public:
bool hasCycle(ListNode *head) {
if(!head) return false;
unordered_map<ListNode *,int> hash;
hash[head]=1;
if(head->next) head=head->next;
else return false;
while(head)
{
if(hash.find(head)==hash.end()) hash[head]=1;
else return true;
head=head->next;
}
return false;
}
};
记得之前看过,左神的视频,这里只要设置两个快慢指针,慢指针每次走一步,快指针每次走两步,如果只要有环,那么他们一定会相遇;至于为什么这样,那是因为快的肯定会追到慢的啊;
class Solution {
public:
bool hasCycle(ListNode *head) {
if(!head) return false;
ListNode * fast=head;
ListNode * slow=head;
int i=2;
while(slow)
{
while(fast&&i>0){
fast=fast->next;
if(!fast) return false;
--i;
}
slow=slow->next;
i=2;
if(slow &&fast &&slow==fast) return true;
}
return false;
}
};
这里的空间复杂度为O(1);
时间复杂度:假设慢指针走到入环节点走了N步,剩下的长度为K,由于每一次快指针比慢指针多走一步,假设此时快指针距慢指针的距离为a;则快指针回到入环节点需要(K-a);此时他们相差是(K-a)/2;然后每一次快指针比慢指针多走一步,因此慢指针在走个(k-a)/2步,快指针就赶上了它,因此慢指针总共走了K-a步;因此以慢指针迭代计算的时间复杂度为O(K-a+N),因此从共的时间复杂度不超过O(n)
来源:https://blog.csdn.net/qq_41983709/article/details/100994858