这一题还蛮有意思的,虽然不太复杂,但是也是一种很简便的算法思想,所以在此做一下记录
题目描述: 141. Linked List Cycle I
Given a linked list, determine if it has a cycle in it.
Follow up: Can you solve it without using extra space?
Subscribe to see which companies asked this question.
解题思想
难点就在于不让消耗空间复杂度,这样怎么办?
我们可以模拟一个“赛跑”的过程:
/**
* 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) {
if( !head ) return false;
ListNode *walk=head,*run=head->next;
while(run&&run->next&&run->next->next){//将run->next放在前面避免发生NULL->next的情况
if(run==walk) return true;
run=run->next->next;//run跳两步
walk=walk->next;//walk只走一步
}
return false;
}
};
————————————————-我是分割线——————————————————
题目描述: 142. Linked List Cycle II
解题思想
难点就在于不让消耗空间复杂度,这样怎么办?
我们可以模拟一个“赛跑”的过程:
题目的要求改成了:
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
现在的问题不是有没有环,而是环开始的位置在哪里,要求更高了,怎么办?
还是“赛跑”的方法,求出环的开始点的偏移量:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head){
if(!head || !(head->next)) return NULL;
ListNode *walk=head,*run=head;
bool isCycle=false;
while(run->next&&run->next->next){
run=run->next->next;
walk=walk->next;
if(walk==run) {isCycle=true; break;}
}
if(!isCycle) return NULL;
//这里非常重要!好好记住这个性质!!!
walk=head;
while(walk!=run){
walk=walk->next; run=run->next;
}
return walk;
}
};
下面还有一种利用样例漏洞的办法,是一开始想出来的办法,比较起来有点low就一笔带过了。。。。需要解释的话可以留言。。。