环型链表

环型链表

题目描述:
  • 给定一个链表,判断链表当中有没有环
    在这里插入图片描述
    在这里插入图片描述

解体思路:

思路一:
  • 可以利用快慢指针的思路,给定两个指针,让两个指针一开始都位于链表头部的位置,然后开始走起来,一个指针每次走一步,一个指针每次走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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章