环型链表

    技术2022-07-10  172

    环型链表

    题目描述:
    给定一个链表,判断链表当中有没有环

    解体思路:

    思路一:
    可以利用快慢指针的思路,给定两个指针,让两个指针一开始都位于链表头部的位置,然后开始走起来,一个指针每次走一步,一个指针每次走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; } };
    Processed: 0.010, SQL: 9