环形链表
题目描述
给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 null。
为了表示链表中的环,评测系统内部用整数 pos 标记尾节点连接到的位置(索引从 0 开始)。如果 pos 是 -1,表示没有环。pos 只用于描述数据,不会作为参数传进来。题目也明确要求不能修改链表。
思路分析
前面如果已经写过快慢指针,这里我更倾向于直接用 set。原因很简单:思路直,不容易在环入口判断上绕晕,代码也短。
遍历链表时,把访问过的节点指针放进集合里。当前节点如果已经在集合中,说明第一次重复遇到的就是环入口;如果一路走到 nullptr 都没重复,那就说明链表无环。
这里存的是节点指针,不是节点值。这个区别不能省,值重复很常见,地址才是真正的唯一标识。
代码实现
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,顺便完成去重,然后遍历其中一个集合,在另一个集合里查找。第二种是利用 set 天然有序的性质,改成双指针同步推进。后者思路更像'两个有序数组求交集',在数据量稍大时通常也更省事。
代码实现
class Solution {
public:
vector<int> intersection(vector<>& nums1, vector<>& nums2) {
;
;
vector<> v;
( e : s1) {
(s(e)) {
v.(e);
}
}
v;
}
};


