环形链表检测
问题描述
给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 null。
为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。注意不允许修改链表。
解题思路
虽然快慢指针法在 C 语言中很经典,但考虑到代码简洁性,这里我们直接使用 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()) {
s.insert(cur);
} else {
return *it;
}
cur = cur->next;
}
return nullptr;
}
};
两个数组中的交集
问题描述
给定两个数组 nums1 和 nums2,返回它们的交集。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。
解题思路
暴力遍历虽然可行,但容易受数组大小影响导致结果重复或效率低下。更稳妥的方案是利用集合去重。
- 去重:先将两个数组分别存入
std::set,利用集合特性自动去重。 - 比对:遍历其中一个集合的元素,检查是否存在于另一个集合中。
- 收集:将找到的元素加入结果向量返回。
此外,这种对比思想也适用于寻找差集或并集,核心在于有序数据的线性扫描。
代码实现
class Solution {
public:
vector<> {
;
;
vector<> v;
( e : s1) {
(s(e)) {
v.(e);
}
}
v;
}
};


