
idea:对于有环结构的链表,判断环结点位置,开始想到遍历链表,直到某一个结点出现第二遍,所以要进行比对的过程,想到前面学到利用哈希表解决相交链表,可以在这使用。不过对于为什么使用_set不太清楚,哈希表的操作及原理下来也要好好补一下
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode*> hash; //创建哈希表
while(head!=NULL){ //判断是否有环结构
if(hash.count(head)) //与已有元素进行比对
return head;
hash.insert(head); //录入哈希表
head=head->next;
}
return NULL;
}
}
复杂度分析
时间复杂度:O(N)O(N),其中 NN 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。
空间复杂度:O(N)O(N),其中 NN 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。
进阶:双指针。 idea:具体是用快慢指针相遇问题,通过数学计算来解决问题,具体算法如下
代码实现:
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head, *slow=head, *p=head;
while(fast!=NULL && fast->next!=NULL && fast->next->next!=NULL){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
while(p!=slow){
p=p->next;
slow=slow->next;
}
return p;
}
}
return NULL;
}
};
复杂度分析
时间复杂度:O(N)O(N),其中 NN 为链表中节点的数目。在最初判断快慢指针是否相遇时,\textit{slow}slow 指针走过的距离不会超过链表的总长度;随后寻找入环点时,走过的距离也不会超过链表的总长度。因此,总的执行时间为 O(N)+O(N)=O(N)O(N)+O(N)=O(N)。
空间复杂度:O(1)O(1)。我们只使用了 \textit{slow}, \textit{fast}, \textit{ptr}slow,fast,ptr 三个指针。
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/linked-list-cycle-ii/solution/huan-xing-lian-biao-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效