Total Accepted: 67741
Total Submissions: 215263
Difficulty: Medium
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
首先要看清的是它会有一部分出现环状 , 而不能看成周期了 。
第一种方法便是 用一个快的指针和一个慢的指针来走,快的速度是慢的两倍。当他们第一次相遇的时候就跳出循环
此时 , 他们离环状开始的节点的距离和从头节点到环状的距离是一样的。因此 。
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *fast , *slow ;
if( head == NULL || head -> next == NULL )
return NULL ;
fast = slow = head ;
do {
slow = slow -> next ;
fast = fast -> next -> next ;
}while(fast!=slow && fast&&fast->next&&fast->next->next) ; // 相等时跳出循环或者到达空值
if(!fast||!fast->next||!fast->next->next)
return NULL ; //判断是否是到达空值
fast = head ;
while (fast){
if(fast == slow)
return slow ; //相等时目标节点
fast = fast -> next ;
slow = slow -> next ;
}
return NULL ;
}
第二种方法就是记录走过的节点,如果出现重复的节点就证明此时是环状开始的节点。
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *p[12345];
int i = 0 ;
int j ;
if( head == NULL || head -> next == NULL )
return NULL ;
while ( head ){
if(i){
for ( j = 0 ; j < i ; j++ ) // 遍历以前走过的节点,看是否出现了相同
if(p[j] == head )
return head ;
}
p[i++] = head ;
head = head -> next ;
}
return NULL ;
}
这种方法需要用一个很大指针数组 。但很容易理解 。