【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>
相关文章推荐
- Linked List Cycle leetcode II java (寻找链表环的入口)
- Leetcode Linked List Cycle II 循环链表入口
- LeetCode-142 Linked List Cycle II
- LeetCode Linked List Cycle II
- 【leetcode】 Linked_List_Cycle_II
- [LeetCode]93. Linked List Cycle II查找链表中环的起始节点
- LeetCode - Linked List Cycle II
- LeetCode: Linked List Cycle II
- [Leetcode] #141#142 Linked List Cycle I & II
- LeetCode 142 Linked List Cycle II
- [leetcode][list][two pointers] Linked List Cycle II
- leetcode 147: Linked List Cycle II
- LeetCode: Linked List Cycle II [142]
- LeetCode141 Linked List Cycle. LeetCode142 Linked List Cycle II
- LeetCode(141)(142) Linked List Cycle I II
- leetcode_c++:链表:Linked List Cycle II(142)
- leetCode--linked-list-cycle-ii
- [LeetCode] Linked List Cycle II
- LeetCode Linked List Cycle II
- 【LeetCode】Linked List Cycle I&II