您的位置:首页 > 其它

【LeetCode】Linked List Cycle II

2014-03-31 11:38 246 查看

参考链接

http://www.cnblogs.com/x1957/p/3406448.html

题目描述


Linked List Cycle II

 

Given a linked list, return the node where the cycle begins. If there is no cycle, return 
null
.
Follow up:

Can you solve it without using extra space?

题目分析

这个题目不仅要求出是否有环,而且还需要指出环开始的结点。

看了各中分析,找出一个最简单的大牛的,这里我讲一下思路



使用快慢指针,快指针是慢指针的2倍速度

假设在红色凸起的地方相遇了。

F走的路程应该是S的两倍

S走的路程S = x + y

F走的路程F = x + y + z + y = x + 2y + z

2*S = F

2x+2y = x + 2y + z

得到x = z

上面是大神的说明,我认为有一个地方需要改动一下

我认为更合理的应该是F = x + (y + z)*k + y (k=1,2....n)


假设x特别长,环特别小,可以s到达环之前f已经在环里转了好多圈了

所以2*S=F

[b]x + (y + z)*k + y = 2([b]x
+ y
)[/b]
[/b]

x = (y
+ z)*k -y = (y + z)*(k -1)+z

不过以上改动不影响算法

在相遇的时候,把slow置为head,fast速度改为1。这时slow从head,fast从相遇的地方开始一起移到。

这时我们会发现当slow起了x时。fast走了(y+z)*(k-1)+z,不难理解,他们会在环开始的地方相遇。

总结

在写代码时:
找出相遇点后,重置slow,再开始找相遇点,应该先判断再移动指针,因为可能环开始的地方就是head。

return NULL;
ListNode *slow = head;
ListNode *fast = head;
while(fast->next != NULL && fast->next->next != NULL)
{
slow = slow->next;
fast = fast->next;
fast = fast->next;
if(fast == slow)			//第一次相遇后,跳出
break;
}
//把slow置到head,fast速度改为1
slow = head;
while(fast->next != NULL && fast->next->next != NULL)
{
if(fast == slow)			//这里需要移动前面,因为相遇的可能就是头结点
return slow;
slow = slow->next;
fast = fast->next;
}


注意两个while循环里的区别

代码

/*
编译环境CFree 5.0

*/
#include
#include

using namespace std;

struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
} ;

void printList(ListNode *head,char *name)
{
printf("%s\n",name);
while(head != NULL)
{
printf("%3d,",head->val);
head = head->next;
}
printf("\n");
}

class Solution {
public:
ListNode* detectCycle(ListNode *head) {
if(head == NULL)
return NULL;
ListNode *slow = head;
ListNode *fast = head;
while(fast->next != NULL && fast->next->next != NULL)
{
slow = slow->next;
fast = fast->next;
fast = fast->next;
if(fast == slow)			//第一次相遇后,跳出
break;
}
//把slow置到head,fast速度改为1
slow = head;
while(fast->next != NULL && fast->next->next != NULL)
{
if(fast == slow)			//这里需要移动前面,因为相遇的可能就是头结点
return slow;
slow = slow->next;
fast = fast->next;
}
return NULL;
}
};

ListNode* listCreate(vector &list, int arr[], int n)
{
if(n <= 0)
return NULL;

for(int i=0;inext = &list[i];
head = head->next;
}
head = &list[0];
return head;
}

//有环
void test0()
{
vector list;
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
ListNode *head = listCreate(list,arr, 10);
printList(head,"head");
list[9].next = &list[3];//制造一个环
Solution so;
if(so.detectCycle(head) != &list[3])
printf("------------------------failed\n");
else
printf("------------------------passed\n");

}
//无环
void test1()
{
vector list;
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
ListNode *head = listCreate(list,arr, 10);
printList(head,"head");
//list[9].next = &list[3];//制造一个环
Solution so;
if(so.detectCycle(head) != NULL)
printf("------------------------failed\n");
else
printf("------------------------passed\n");

}

void test2()
{
vector list;
int arr[2] = {0,1};
ListNode *head = listCreate(list,arr, 2);
printList(head,"head");
list[1].next = &list[0];//制造一个环
Solution so;
if(so.detectCycle(head) != &list[0])
printf("------------------------failed\n");
else
printf("------------------------passed\n");

}

int main()
{
test0();
test1();
test2();
return 0;
}

<script src="https://code.csdn.net/snippets/266236.js"></script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表