[leetcode] 142.Linked List Cycle II
2015-08-20 13:34
274 查看
题目:
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?
题意:
给定一个链表,如果有环的话,找出环的开始节点,否则返回NULL。
思路:
首先来确定是否存在环,依旧使用一快一慢两个指示器,一个每次往前走两步,一个每次往前走一步,如果遇到NULL了,说明能够访问到链表的结尾,所以不存在环。否则的话两者一定在环中相遇。
假设慢节点走了k步到达环的入口处,那么快结点此时已经在环中走了k步,假设环的长度是length,并且假设k = m*length + n,那么此时快结点离环的入口节点的距离是n。接下来慢节点也会进入环,并且按照运动方向,此时快结点与慢节点其实相距是length - n的长度,接下来就是追逐戏,快结点去追慢节点,慢节点每走一步,快结点会走两步,所以它们之间的距离就会少一,所以追逐了length - n步之后,它们就会在环中相遇了。此时这两个节点离环的入口位置距离是n。而我们知道从链表的头结点倒环的入口距离是k,而k = m*length + n,那么此时我们让快结点从链表头结点开始,但是此时快结点变成跟慢节点一样的速度,那么两个节点一定会在环的入口处相遇,因为快结点到达入口时,慢节点正好在里面绕了m圈后,又走了n步,正好就在环的入口处。
以上,代码如下:
2.思路二,同样是快慢节点先在环中相遇。然后我们找出环的长度,让慢节点不动,快结点继续一步一步的走,直到快结点再次走到慢节点所在的位置,统计出长度length。接下来,让先行节点先走length,然后后行节点也开始往前走,所以当两者再次相遇的时候,正好是在环的入口处。因为先行节点正好多走了一个环的长度。
以上。
代码如下:
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?
题意:
给定一个链表,如果有环的话,找出环的开始节点,否则返回NULL。
思路:
首先来确定是否存在环,依旧使用一快一慢两个指示器,一个每次往前走两步,一个每次往前走一步,如果遇到NULL了,说明能够访问到链表的结尾,所以不存在环。否则的话两者一定在环中相遇。
假设慢节点走了k步到达环的入口处,那么快结点此时已经在环中走了k步,假设环的长度是length,并且假设k = m*length + n,那么此时快结点离环的入口节点的距离是n。接下来慢节点也会进入环,并且按照运动方向,此时快结点与慢节点其实相距是length - n的长度,接下来就是追逐戏,快结点去追慢节点,慢节点每走一步,快结点会走两步,所以它们之间的距离就会少一,所以追逐了length - n步之后,它们就会在环中相遇了。此时这两个节点离环的入口位置距离是n。而我们知道从链表的头结点倒环的入口距离是k,而k = m*length + n,那么此时我们让快结点从链表头结点开始,但是此时快结点变成跟慢节点一样的速度,那么两个节点一定会在环的入口处相遇,因为快结点到达入口时,慢节点正好在里面绕了m圈后,又走了n步,正好就在环的入口处。
以上,代码如下:
/** 1. Definition for singly-linked list. 2. struct ListNode { 3. int val; 4. ListNode *next; 5. ListNode(int x) : val(x), next(NULL) {} 6. }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if(head == NULL || head->next == NULL)return NULL; ListNode *node1 = head->next, *node2 = head->next->next; while(node2 != NULL && node1 != node2) { node1 = node1->next; node2 = node2->next; if(node2 == NULL)break; node2 = node2->next; } if(node2 == NULL)return NULL; ListNode *h2 = head->next; node1 = node1->next; while(node1 != node2) { node1 = node1->next; h2 = h2->next; } ListNode *h1 = head; while(h1 != h2) { h1 = h1->next; h2 = h2->next; } return h1; } };
2.思路二,同样是快慢节点先在环中相遇。然后我们找出环的长度,让慢节点不动,快结点继续一步一步的走,直到快结点再次走到慢节点所在的位置,统计出长度length。接下来,让先行节点先走length,然后后行节点也开始往前走,所以当两者再次相遇的时候,正好是在环的入口处。因为先行节点正好多走了一个环的长度。
以上。
代码如下:
/** * 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 == NULL || head->next == NULL)return NULL; ListNode *node1 = head->next, *node2 = head->next->next; while(node2 != NULL && node1 != node2) { node1 = node1->next; node2 = node2->next; if(node2 == NULL)break; node2 = node2->next; } if(node2 == NULL)return NULL; ListNode *h2 = head->next; node1 = node1->next; while(node1 != node2) { node1 = node1->next; h2 = h2->next; } ListNode *h1 = head; while(h1 != h2) { h1 = h1->next; h2 = h2->next; } return h1; } };
相关文章推荐
- synchronized与static synchronized 差异
- 正则表达式相关(group用法)
- WSDL教程
- HDU-4786 Fibonacci Tree(最小生成树[Kruskal])
- Myeclipse导出war包
- web service(SOAP)与HTTP接口的区别
- C#线程同步自动重置事件——AutoResetEvent
- javascript form 第22节
- android中在代码中创建应用的快捷图标
- 【JavaScript】javaScript基础知识回顾
- POJ3292——Semi-prime H-numbers
- 关于mybatis的传递参数报错Type handler was null on parameter mapping for property 'userId'.
- centos 7 第一次启动hadoop生态之zookeeper-3.4.6
- ios uitableview header不随着滚动
- HTTP协议详解(真的很经典)
- 使用statsvn统计svn代码量方法
- [web安全] Webshell的检测
- linux 文件属性
- Spark: java.lang.IllegalStarteException: unread block data
- .NET 图片格式转换