鏈表相關問題分析part2(尋找公共節點,是否有環)

這篇文章主要是分析一下鏈表是否有環問題(LeetCode141題)主要方法類似於上一篇文章
https://blog.csdn.net/you558/article/details/102409450

題目描述如下:
圖片來源於LeetCode

思路一:
遍歷鏈表,利用一個哈希表保存遍歷到的節點地址,同時判斷該節點的下一個節點是否在保存的哈希表中,若存在,則說明鏈表有環;反之,若遍歷到某一節點爲nullptr,則說明鏈表無環。

具體實現代碼如下:

/**
 * 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* p=head;
        unordered_set<ListNode*>sl;
        while(p!=nullptr&&p->next!=nullptr)
        {
            sl.insert(p);
            auto ret=sl.find(p->next);
            if(ret!=sl.end())return true;
            p=p->next;
        }
        return false;
    }
};

思路二:
具體實現步驟如下

  1. 定義兩個指針slow 和fast,分別指向head和head的下一個節點
  2. 開始遍歷,slow每次移動一個節點,fast每次移動兩個節點
  3. 若fast=slow,且不爲nullptr,說明鏈表有環

說明:
如果鏈表有環,那麼經過若干次移動後,slow和fast兩個指針必然進入整個鏈表的環形區域(可以將其想象成圓周跑道上的兩個運動員,速度一快一慢),slow每次移動一步,fast每次移動兩步,也就是fast離slow的距離每次減小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) {
        if(head==0||head->next==0)return false;
        ListNode *slow=head,*fast=head->next;
        while(fast!=0&&fast->next!=0)
        {
            
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)return true;
        }
        return false;
    }
};

總結:以上兩種方法顯然第二種較優,其空間複雜度爲O(1);;兩種方法的時間複雜度均爲O(n);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章