141. Linked List Cycle (Easy)
ps:能力有限,若有错误及纰漏欢迎指正、交流
- Linked List Cycle (Easy)
https://leetcode.cn/problems/linked-list-cycle/description/
给定一个链表,判断该链表是否存在环
- 方法一:暴力解法
将之前访问过的元素全部储存,与现在访问元素的next进行对比,有相同便存在环
时间复杂度:O(n^2) 此处采用 静态存储需申请大于10^4的内存,而使用 静态内存则有所优化,但每增加一个元素就得申请一个元素的地方
空间复杂度:O(n)
- 方法二:快慢指针
思路:若快指针 **追上 **慢指针则 存在环
bool hasCycle(struct ListNode *head) {
struct ListNode *slowP=head;
struct ListNode *quickP=head;
/*疑问:假设存在环,会不会出现快指针追不上慢指针的情况(因为环上元素的个数及快慢指针速度的问题)*/
do{
if(slowP==NULL||quickP==NULL||quickP->next==NULL){
return false;
}
slowP=slowP->next;
quickP=quickP->next->next;
}while(slowP!=quickP);/*相遇*/
return true;
}
时间复杂度:O(n)
-
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。而初始距离为环的长度,因此至多移动 N 轮。
另外的 角度:如果 加快(即增大快指针的增量)快指针,则可以更快的判断 不存在环路。那么,出现两个疑问:
- 1.会不会出现无法相遇的情况?
- 2.放慢快指针,一定会加快 存在环路的判断速度吗?
空间复杂度:O(1),仅仅使用了两个指针
另外
这里请注意:
如果使用 while则需要将
struct ListNode *slowP=head;
struct ListNode *quickP=head;
修改为:
struct ListNode *slowP=head;
struct ListNode *quickP=head->next;
否则,无法进入while循环
do...while与 while类似,但do...while会确保至少执行一次循环。