Determine whether there is a cycle in a singly linked list

Method 1: Hash table 

Idea: Traverse a singly linked list. Each time a node is traversed, determine whether the node is in the set. If the node is not in the set, add it. If it is in the set, it means there is a cycle and return true;

  • The time complexity is O(N). In the worst case, we need to traverse each node once.
  • The space complexity is O(N), mainly the overhead of the hash table. In the worst case, we need to insert each node into the hash table once.
  •     /**
         * 方案一:遍历链表,若节点不在集合中则加入,相反若在集合中,则说明存在环,返回true
         * @param head
         * @return
         */
        public static boolean hasCycle(ListNode head) {
            HashSet<ListNode> set = new HashSet<>();
            while(!set.contains(head)){
                /*空指针异常*/
                /*if(head.next == null){
                    return  false;
                }*/
                if(head == null){
                    return  false;
                }
                set.add(head);
                head = head.next;
            }
            return true;
        }

    Method 2: Fast and slow pointers

  • Idea: Two people A and B walk along the singly linked list at different speeds. If they can meet, it means there is a cycle.

    We define two pointers, one fast and one full. The slow pointer moves only one step at a time, while the fast pointer moves two steps at a time. Initially, the slow pointer is at position head, and the fast pointer is at position head.next. In this way, if the fast pointer catches up with the slow pointer during the movement, it means that the linked list is a circular linked list. Otherwise, the fast pointer will reach the end of the linked list, and the linked list is not a circular linked list.

  • Time complexity: O(N), when there is no ring in the linked list, the fast pointer will reach the end of the linked list before the slow pointer, and each node in the linked list will be visited at most twice.

    When there is a ring in the linked list, the distance between the fast and slow pointers will decrease by one after each round of movement. The initial distance is the length of the ring, so it moves at most NN rounds.

    Space complexity: O(1). We only use the extra space of two pointers.

  • /**
         * 方案二:A和B两个人以不同的速度沿着单链表走步 ,若两人能相遇,则说明存在环
         * @param head
         * @return
         */
        public static boolean hasCycleTwo(ListNode head) {
            ListNode first = head;
            ListNode two = head;
            /**
             * 如果A能走到头则说明,不存在环
             */
            if (first != null) {
                first = first.next;
            }else{
                return false;
            }
            /**
             * 若B能走到头则说明不存在环
             */
            if (two != null) {
                two = two.next;
                if (two != null) {
                    two = two.next;
                }else {
                    return false;
                }
    
            }else{
                return false;
            }
            /**
             * 若A和B能相遇则说明,存在环
             */
            while(first != two) {
                if (first != null) {
                    first = first.next;
                }else{
                    return false;
                }
                if (two != null) {
                    two = two.next;
                }else{
                    return false;
                }
                if (two != null) {
                    two = two.next;
                }else {
                    return false;
                }
            }
            return true;
        }

public boolean hasCycleTwos(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;
        }

Guess you like

Origin blog.csdn.net/weixin_36416680/article/details/118611197