循环链表是否有环

157 阅读1分钟

1. 判断循环链表是否有环

1.1 思路一: 使用哈希表存储所有的值

每个访问的节点,放入哈希表中,如果下一个节点已经存在于哈希表中,表示有环

时间和空间复杂度都是O(N)

1.2 思路二:使用快慢指针处理相应的值

同时出发,如果有环,跑的快的指针一定会和慢指针再次相遇

时间复杂度O(N),空间复杂度O(1)

1.3 java代码实现如下

package com.leecode.competition.link;
​
import java.util.HashSet;
import java.util.logging.Handler;
​
public class CircleLinkNode {
    
    public void cirecleLinkNodeTest() {
        LinkNode node = new LinkBase().createCircleLinkNode();
        System.out.println("use point to check the circle.");
        System.out.println(isCircleWithPoint(node));
​
        System.out.println("use hashSet to check the circle.");
        System.out.println(isCircleWithHashSet(node));
    }
​
    //给定一个链表,判断链表中是否有环。
    public boolean isCircleWithPoint(LinkNode node) {
​
        if (node == null || node.getNext() == null) {
            return false;
        }
        LinkNode singleRunPoint = node;
        LinkNode multiRunPoint = node;
        singleRunPoint = singleRunPoint.getNext();
        multiRunPoint = multiRunPoint.getNext().getNext();
        while (singleRunPoint != null && multiRunPoint != null) {
            if (singleRunPoint == multiRunPoint.getNext()) {
                return true;
            }
            singleRunPoint = singleRunPoint.getNext();
            multiRunPoint = multiRunPoint.getNext().getNext();
        }
​
        return false;
    }
​
    public boolean isCircleWithHashSet(LinkNode node) {
​
        if (node == null) {
            return false;
        }
        HashSet<LinkNode> hashSet = new HashSet<>();
​
        while (node != null) {
            System.out.print(node.getVal() +" ");
            if (!hashSet.add(node)) {
                return true;
            }
            node = node.getNext();
        }
​
        return false;
    }
​
​
}