一、环形链表
题目描述
给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 null。
为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。注意不允许修改 链表。
解题思路
在之前的讲解中我们提到过快慢指针法,但这里我们尝试用 C++ STL 的 set 容器来实现。核心逻辑是遍历链表,将节点指针存入集合中。如果当前节点已经在集合里了,说明遇到了环的入口点;如果遍历结束都没重复,则无环。
需要注意的是,我们存储的是节点的指针地址,而不是节点的值。因为不同节点可能拥有相同的值,只有指针地址才是唯一的身份标识。
代码实现
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
std::set<ListNode*> s;
ListNode* cur = head;
while(cur) {
auto it = s.find(cur);
if(it == s.end()){
// cur 不在 set 对象中,就插入到 set 对象中
s.insert(cur);
} else{
// cur 在 set 对象中就带环,并且该节点就是环入口点
return *it;
}
cur = cur->next;
}
return nullptr;
}
};
二、两个数组中的交集
题目描述
给定两个数组 nums1 和 nums2,返回它们的交集。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。
解题思路
暴力遍历虽然可行,但效率低且容易出错(例如去重处理不当会导致结果包含重复项)。更稳妥的方案是利用哈希集合的特性。
- 去重:先将两个数组分别放入
std::set或std::unordered_set中,自动完成去重。 - 查找:遍历其中一个集合的元素,检查是否存在于另一个集合中。
- 对比算法扩展:其实这种思想可以推广到求差集、并集等场景。对于有序数据,双指针对比往往比哈希表更高效,空间复杂度更低。


