题目
截图自官方
代码
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
// 没做出来。官方解法1,用hashset来记录是否有重复。应用看笔记
// 注意hashset的add是有boolean返回值的。
// public boolean hasCycle(ListNode head) {
// HashSet<ListNode> set=new HashSet();
// while(head!=null){
// if(set.contains(head)){
// return true;
// }
// set.add(head);
// head=head.next;
// }
// return false;
// 官方解法1
// while(head!=null){
// if(!set.add(head)){
// return true;
// }
// head=head.next;
// }
// return false;
// 这样也行,都是利用了set.add的返回值
// while(head!=null){
// if(set.add(head)){
// head=head.next;
// } else return true;
// }
// return false;
// }
// 快慢指针,如果链表中存在环,则快指针一定会“追上”慢指针。快的一次跨两步,注意判断空指针。空间复杂度O(1)。
// 时间复杂度,假设直线部分有N,则slow移动N次,进入环后假设有K个节点,最差情况first和slow差K步,但是每迭代一次他们的距离减1,因此K次迭代后一定追上:O(K+N)=O(n)
public boolean hasCycle(ListNode head) {
if(head==null){
return false;
}
ListNode slow=head;
ListNode fast=head.next;
while(slow!=fast){
if(fast==null||fast.next==null){
return false;
}
slow=slow.next;
// 注意在前面判断空指针
fast=fast.next.next;
}
return true;
}
}
笔记
这个题一定注意那些引用型变量(例如ListNode)在借助容器类来比较两个对象是否相等(唯一与否)的细节:应该是只要没有new一个,进行add操作时传的依旧是引用,那么contains检查时,也是用引用值来比较是否唯一:
HashSet<Person> set=new HashSet();
Person person1=new Person(1);
boolean add1 = set.add(person1);
System.out.println(add1);/*true*/
boolean add2 = set.add(person1);
System.out.println(add2);/*false*/
boolean add3 = set.add(new Person(1));
System.out.println(add3);/*true*/ System.out.println(set);/*[test.LeetCode.Person@61443d8f, test.LeetCode.Person@445b84c0]*/