今天做到了这个题目,重温了下左神的方法,同时也和师兄讨论了下,为什么在第二次相遇时,就是其入环口。
求解入环口的方法:
快慢指针法(左神)
步骤:
- 设置两个指针一个快指针quick,一个慢指针slow(快指针一次走两步,慢指针一次走一步,如果他们能相遇则说明有环)
- 相遇后,快指针重新回到头结点head,之后,两个结点一起前进,均一次走一步,再次相遇处则为入环口。
代码
public static Node getCircleEntrance(Node head) {
if (head.next == null || head.next.next == null) {
return null;
}
Node quick = head.next.next;
Node slow = head.next;
while (quick != slow) {
if (slow.next == null || quick.next.next == null) {
return null;
}
quick = quick.next.next;
slow = quick.next;
}
//相等时说明有环
quick = head;
while (quick != slow) {
quick = quick.next;
slow = slow.next;
}
return slow;
}
当时写代码时,在想为什么第二次相遇时就是入环点呢?讨论了一波,总结如下:
同时,也在考虑,如果不用快慢指针,是否可以用HashSet集合来存储每一个节点,如果有重复的节点被存入,返回该节点即可。(这样的话会增加空间开销)
public static Node circleIndex(Node head){
HashSet<Node> set = new HashSet<>();
Node cur = head;
while(cur.next != null){
if(set.contains(cur)){
return cur;
}
set.add(cur);
cur = cur.next;
}
return null;
}