此题有两种解法:(1.Set集合 2.快慢双指针)
题解一:(Set集合)
我们知道Set集合的结构特点是不允许存放重复的元素!那我们就可以考虑,假如链表有环,遍历链表节点的时候就肯定会重复遍历环节点。如果将重复的链表结点放进Set集合里,那Set集合就会返回false。我们就可以利用Set集合返回的false判断链表是否有环。
代码如下:
Set<ListNode> set = new HashSet<>(); while(head!=null && head.next!=null){ if(!set.add(head)){//判断set是否重复加入相同的链表结点 return true;//说明有环 } head= head.next;//继续遍历链表节点 } //当链表遍历完了,说明链表不存在环,不然while循环不会跳出 return false;
题解二:(快慢双指针)空间复杂度比利用Set低
双指针相信大家都碰到过了,这里是利用快慢两个指针同时对链表进行遍历,其中最主要的思想是:(快指针是跳着一步遍历链表!慢指针一步一步遍历链表!)假如链表有环,那么快指针一定会提前到达环里,慢指针会晚一步,然后快慢指针最后会相遇。假如链表没有环,快指针肯定会提前到达链表结尾,因此结束遍历。
代码如下:
if(head==null||head.next==null){ return false; } //双指针,降低空间复杂度。 ListNode slow=head,quick=head.next; while(slow!=quick){//只要有环,两个指针必相遇,就会跳出 if(quick==null || quick.next==null){//快指针到达链表尾部,结束。 return false; } slow = slow.next; quick = quick.next.next; } return true;