141.环形链表
目录
- 141.环形链表
- 一、哈希表
- 二、双指针
 
 
 
 

一、哈希表
最容易想到的方法就是遍历所有节点,每次遍历到一个节点的时候,判断该节点此前是否被访问过
我们可以使用哈希表来存储所有已经访问过的节点
每次到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入到哈希表中,重复这一操作,直到遍历完整个链表为止
值得一提的是,这里我们使用HashSet,Set集合的特点是什么?即该集合中不会出现重复的元素,如此一来,就很好判断了
    public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<ListNode>();
        while(head!=null){
            //如果向哈希Set中加入节点失败(即该Set中已经有了重复的元素)
            if(!set.add(head)){
                return true;
            }
            head = head.next;
        }
        return false;
    }
二、双指针
本题的快慢指针法,需要我们先了解一下Floyd判圈算法(龟兔赛跑算法)
假设乌龟和兔子从链表上同一节点开始移动,兔子跑得快,乌龟跑得慢,如果链表中没有环,那么兔子将一直处在乌龟的前方
如果链表中有环,那么兔子会先于乌龟进入环,并一直在环中移动;等到乌龟进入环后,由于兔子的速度快于乌龟,所以兔子一定会在某个时刻追上乌龟





 可以根据这个思路来解决这个问题,我们定义两个指针,一快一慢。慢指针每次只移动一步,而快指针每次移动两步
初始时,慢指针在head位置,快指针在head.next位置
这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表
否则快指针将到达链表尾部,该链表不为环形链表
    public boolean hasCycle(ListNode head) {
        if(head==null||head.next==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;
    }











![[javascript核心-08] V8 内存管理机制及性能优化](https://img-blog.csdnimg.cn/img_convert/81364972f4fea6cdac2ce1d20746b796.png)







