您的位置:首页 > 其它

leetcode:Linked List Cycle II

2014-06-14 23:22 344 查看
判断给出的单链表是否是一个循环的链表,如果是一个循环的单链表的话,输出循环开始的节点

最简单的做法,对整个单链表进行hash,但是要占用o(n)的空间复杂度,

public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode node = head;
Integer t ;
//ListNode end = new ListNode(-1);
HashMap<ListNode, Integer> map = new HashMap<>();
while(node != null){
t = map.get(node);
if(t == null){
map.put(node, node.val);
}
else {
return node;
}
node = node.next;
}
return null;
}
}


题目要求不使用额外的辅助空间,通过查询discuss;

通过控制双指针进行操作,一个指针的步长为1,另外一个指针的步长为2,

如果存在循环圈,步长为2的指针肯定会跟步长1的指针走到同一个node上面;

此时,我们定义x表示从头指针head到开始循环节点的长度,定义y为循环链表的长度

如果链表存在环,假设步长1指针和步长2指针在循环圈内的第m个node重叠

那么步长1指针走了有 x + ty + m步

步长2指针走了x + ky + m步

因为 步长2 = 2倍的步长1

所以可以知道 2(x + ty + m)= x + ky + m

故(k-t)y = x + m; 在循环圈内走多x步就可以到达开始循环的头结点了!get it

public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode node1 = head;
ListNode node2 = head;
do{
if(node1 == null || node2 == null){
return null;
}
node1 = node1.next;
node2 = node2.next;
if(node2 == null){
return null;
}
node2 = node2.next;
}while(node1 != node2);
node1 = head;
while(node1 != node2){
node1 = node1.next;
node2 = node2.next;
}
return node1;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: