思路1:这道题如果就这么遍历下去,那么出现一个环就是死循环了,所以想到一个骚办法,也算是投机取巧吧,把遇到的每个数字都置INT32_MAX,在置之前先判断这个值是不是INT32_MAX,如果是则说明这是个环,如果不是,继续遍历下去;
所幸,数据里没并没有INT32_MAX,哈哈哈哈!!!
/**
* 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* now=head;
while(now!=NULL)
{
if(now->val==INT32_MAX)
{
return true;
}
now->val=INT32_MAX;
now=now->next;
}
return false;
}
};
思路1其实有点类似Hash法,这里的Hash法就是把指针所代表的地址作为参数,得到一个hash值再加入到集合中,每次加入之前先判断集合中是不是已存在,若已存在则说明存在环,若一直遍历结束,则说明不存在环;
思路2:快慢指针(双指针)法,快指针每次走两步,慢指针每次走一步;那么无环的情况下,快指针一定先到达终点;如果出现环,情况1:快指针回到慢指针之后的位置,那么快指针一定在某个时刻能追上慢指针,情况二:快指针回到慢指针之前的位置,那么快指针又会进入环,依次类推,总会回到慢指针后再追上慢指针;所以当快指针追上慢指针时,表示存在环;
简单地说就是:2 个人在环形跑道上赛跑,从同一个起点出发,一个跑得快,一个跑得慢,在某一时刻,速度快的必定会追上速度慢的,只要是跑道是环形的;
题目有一个很可爱的题解,标记一下:这是一个有趣的视频题解:快慢指针
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == NULL || head->next == NULL){
return false;
}
ListNode* slow = head;
ListNode* fast = head->next;
while(slow != fast){
if(fast == NULL || fast->next == NULL){
// 如果没有环,快指针会先到达结尾
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};