lc hot 100之:环形链表
链表的题目感觉很多的思路都是【快慢双指针】或【三状态指针】:pre, cur, next.
分享几题lc hot 100的链表题目~
第一题:
首先直接的思路是:如何判断下一个指针指向的链表已被访问过?即访问到了已访问的值。
方法一:【哈希表】,这里用的是unordered_set
class Solution {
public:bool hasCycle(ListNode *head) {if(head==NULL){return false;}// ListNode* cur=head;unordered_set<ListNode*>m;while(head!=NULL){if(m.count(head))return true;m.insert(head);head=head->next;}return false;}
};
这个方法有额外空间。
方法二:快慢指针
这个方法比较巧妙,空间复杂度为o(1),所以应该要在链表本身上想办法。这个思路在找链表中点中也有类似(快慢指针,快的到末尾时慢的到中间)。
题解中形容为“龟兔赛跑”:在同一个跑道上,如果有环的情况下,快的兔子一定会和慢的龟相遇。还可以类比“相对速度”(比较难想到hh)
如果无环的话,fast->next为空就出界咯~
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;}
};
有两个细节是:同时从起点出发+先后移指针再比较是否相遇。
留几个我还没想明白的问题吧:为什么只能比较内存地址是否一致,不能比较节点的 val?(我试了会报错)
还有有两个细节是:同时从起点出发+先后移指针再比较是否相遇。,这里能否再解释下?如果快慢指针的初始值一个是head,一个是head->next为什么会出错呢?