環型鏈表

環型鏈表

題目描述:
  • 給定一個鏈表,判斷鏈表當中有沒有環
    在這裏插入圖片描述
    在這裏插入圖片描述

解體思路:

思路一:
  • 可以利用快慢指針的思路,給定兩個指針,讓兩個指針一開始都位於鏈表頭部的位置,然後開始走起來,一個指針每次走一步,一個指針每次走2步,如果說鏈表是有環的話,那麼走的快的鏈表,就會先進入到環裏面,然後一直在環裏面繞圈圈,慢的指針也會一步一步走到環的裏面,如果有環的話,那麼最終兩個指針一定是會相遇的,那麼就可以通過快慢指針去判斷鏈表裏面到底有沒有環。
    在這裏插入圖片描述
  • 代碼如下所示:
/**
 * 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) 
    {
        ListNode *fast=head;
        ListNode *slow=head;
        while(fast&&fast->next)
        {
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)
                return true;
        }
        return false;
    }
};
  • 還有一個問題需要去考慮------就是
    在這裏插入圖片描述
    快的指針走3步,慢的指針走一步可以嗎?—答案是不可以的,因爲如果快的指針和慢的指針的差值剛好是鏈表的長度的話,那麼就算鏈表有環,快的指針和慢的指針也是不可能會相遇的,那麼爲什麼要一個走一步,一個走兩步呢?----因爲鏈表中至少是要有一個結點的,而且1這個數字是可以被任意的數字所整除的。當兩個指針都進入到環裏面的時候,那麼兩個指針的之間的差值就是一直在縮小的,一直在縮小,那麼到最後肯定是會相遇的。
快慢指針的複雜度分析

在這裏插入圖片描述

思路二:利用哈希表
  • 哈希表法:每訪問一個結點,檢查該結點是否在哈希表中,如果在,則說明存在環,return true;否則,將該結點加入哈希表中。最終,若不存在環,遍歷將結束,然後return false。就是看每個結點被訪問的次數,一旦有一個結點被訪問的次數是大於1的,那麼這個鏈表就一定是存在環的
/**
 * 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) 
    {
        unordered_map <ListNode *,int> ret;
        while(head)
        {
            ret[head]++;
            if(ret[head] > 1)      
                return true;
            head = head->next;
        }
        return false;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章