您的位置:首页 > 其它

[Leetcode]Linked List Cycle

2015-04-30 13:14 393 查看
Given a linked list, determine if it has a cycle in it.

Follow up:

Can you solve it without using extra space?

给定一个链表,不使用额外空间,判断它是否有环;

给出链表结构

struct ListNode {
int val;//存储节点的值
ListNode *next;//指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {}
};


思路1:

因为链表可能是有环的,或者是无环的。当存在环的时候,就能回到链表的头部,因此可以采取比较投机取巧的办法,该办法是建立在可以修改链表的值的基础之上的,如果不能修改链表中存储的数据,就不能用该方法。

我们可以遍历这个链表,每访问一个节点,就把该节点的值设为一个特殊值。当存在环的时候,就会再次访问到头节点,因为我们不知道什么时候会回到或者能否回到头结点,所以我们遍历的时候就要获取节点的值,然后跟特殊值比较,如果相等,就是说这个节点之前我们访问过了,就是说存在环。否则,不存在环。

bool hasCycle(ListNode *head)
{
if(head == NULL)//如果为空,肯定不存在环啦;
return false;
int flag = 2147483648;//这是4字节 int 类型所能存储的最大值
ListNode *p =head;
while(p!=NULL)
{
if( p->val == flag)
return true;
p->val = flag;
p = p->next;
}
return false;
}


思路1 太取巧了,还修改了链表里面存储的数据,不建议使用

思路2:

我们可以设置两个指针,一个快指针,一个慢指针。就像在400米环形跑道上跑步了两个人,一个跑得快,一个跑得慢,跑的快的人肯定会“追上”跑的慢的人。所以,当链表存在环的时候,快指针一定能“追上”慢指针。

我们设快指针每次跑两步,慢指针每次跑一步

bool hasCycle(ListNode *head)
{
if(head == NULL)
return false;
ListNode *pslow = head;
ListNode *pfast = head;
//因为快指针跑的快,如果没环,肯定它先到链表尾部
//所以慢指针就不用判断为空了
while(pfast !=NULL && pfast->next !=NULL)
{
pslow = pslow->next;
pfast = pfast->next->next;
if(slow == pfast)//快指针追上慢指针
return true;//存在环
}
return false;//能跳出循环,表示快指针已到链尾,没有环
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 笔记 算法