思路一:跟昨天差不多的题目,还是可以一样使用哈希表存结点指针,若该节点指针已存在,则返回该指针,若不存在则往后走,若该节点指针为null,返回null
思路二:双指针法,一开始有想到双指针解决,因为做过双指针的循环题目,但是解决不了入口的问题。看了题解差不多,感觉真的妙极了!大致结论就是:一个在双指针相遇的点开始,一个点在开头开始,一次各走一步,最后两个指针就会相遇在入口处。
证明:
快指针走到相遇点的步数:x+y+n(z+y)
慢指针走到相遇点的步数:x+y
同时快指针一次走两步,慢指针一次走一歩,所以:快指针步数 = 2*慢指针步数
所以:x+y+n(z+y) = 2*(x+y)
整理得: 所求 x = (n - 1) (y + z) + z
解读:从相遇结点开始走的指针,总会与从开头开始走的指针相遇,且走的步数就是x
思路一通过代码(java)
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
/*
一边遍历链表,一边检查哈希表中是否存在已存在该指针,若存在,则返回该指针。若当前指针为空,则返回null
*/
//创建哈希表
Set<ListNode> hash = new HashSet<>(1024);
//遍历链表
while(head != null)
{
if(hash.contains(head))
{
return head;
}
hash.add(head);
head = head.next;
}
return null;
}
}
思路二通过代码(java)
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
//创建双指针
ListNode slow = head;
ListNode fast = head;
//快指针遍历
while(fast != null)
{
fast = fast.next;
if(fast == null)
{
break;
}
fast = fast.next;
slow = slow.next;
//快慢指针相遇,说明循环
if(fast == slow)
{
//慢指针回归头部
slow = head;
while(slow != fast)
{
//快慢往后走
slow = slow.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
}