LeetCode 141 The LeetCode Road of HERODING

Given a linked list, determine whether there is a ring in the linked list.

If there is a node in the linked list that can be reached again by continuously tracking the next pointer, then there is a ring in the linked list. In order to represent the rings in a given linked list, we use the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, there are no rings in the linked list. Note: pos is not passed as a parameter, just to identify the actual situation of the linked list.

If there is a ring in the linked list, return true. Otherwise, it returns false.

Advanced:

Can you solve this problem with O(1) (ie, constant) memory?

Example 1:
Insert picture description here

Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a ring in the linked list, and its tail is connected to the second node.

Example 2:
Insert picture description here

Input: head = [1,2], pos = 0
Output: true
Explanation: There is a ring in the linked list, and its tail is connected to the first node.

Example 3:
Insert picture description here

Input: head = [1], pos = -1
Output: false
Explanation: There is no ring in the linked list.

Problem-solving idea:
Quite simple problem-solving idea is to continuously traverse. If it exceeds 10,000, it means that it is in an endless loop. The test sample is less than 10,000 at most, so the problem can be solved in this way. The code is as follows:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool hasCycle(ListNode *head) {
    
    
        int count = 0;
        bool flag = false;
        while(head){
    
    
            count ++;
            if(count > 10000){
    
    
                flag = true;
                break;
            }
            head = head -> next;
        }
        return flag;
    }
};

Method two, fast and slow pointer method. First, one pointer goes first at a distance of 2, and the other pointer goes at a distance of 1. If there is an encounter before the end, then it means that there is a loop. This method is more reliable than the above method. The code as follows:

public boolean hasCycle(ListNode head) {
    
    
    if (head == null || head.next == null) {
    
    
        return false;
    }
    ListNode slow = head;
    ListNode fast = head;
    while (slow != fast) {
    
    
        if (fast == null || fast.next == null) {
    
    
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
}

Method three, hash table method, store the current node when traversing, if it is found to appear repeatedly in the hash table, it means that there is a loop, the code is as follows:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool hasCycle(ListNode *head) {
    
    
        set<ListNode*> s;
        bool flag = false;
        while(head){
    
    
            if(s.count(head)){
    
    
                flag = true;
                break;
            }
            s.insert(head);
            head = head->next;
        }
        return flag;
    }
};

Guess you like

Origin blog.csdn.net/HERODING23/article/details/108971839