壁仞科技 AI Infra 实习 一面
Q: 链表相交问题如何判断?
判断两个单链表是否相交(存在公共节点):
方法一:双指针法(最优):
- 指针 A 从链表 A 头开始,指针 B 从链表 B 头开始
- A 遍历完链表 A 后从链表 B 头继续;B 遍历完链表 B 后从链表 A 头继续
- 如果相交:两指针会在交点相遇(各走 lenA + lenB - common 步)
- 如果不相交:两指针都走完 lenA + lenB 步后同时到达 nullptr
原理:设 A 链表独有部分长 a,B 链表独有部分长 b,公共部分长 c。指针 A 走 a+c+b 步到达交点,指针 B 走 b+c+a 步到达交点。路径长度相同所以同时到达。
**时间 O(n+m),空间 O(1)**。
方法二:将链表 B 尾部接到 A 头部形成环,用快慢指针判断是否有环。有环则相交。但会修改链表结构(需恢复)。
方法三:哈希集合。遍历 A 将所有节点存入 HashSet,再遍历 B 检查是否有节点在集合中。O(n+m) 时间 O(n) 空间。
Q: TopK问题:找最大的K个数用大根堆还是小根堆?
用小根堆(最小堆),堆大小固定为 K。
算法:
- 先将前 K 个元素建小根堆
- 遍历剩余元素:若当前元素 > 堆顶(堆中最小值),则替换堆顶并 heapify
- 遍历完成后堆中即为最大的 K 个数
为什么用小根堆而非大根堆:
- 小根堆维护”当前最大 K 个数中的最小值”在堆顶,作为门槛——新元素超过这个门槛才有资格进入 top-K
- 大根堆若要找 top-K,需要把所有 N 个元素放入后逐一弹出 K 次,空间 O(N) 且时间 O(N + K*logN)
- 小根堆只需 O(K) 空间,时间 O(N * logK)
复杂度:时间 O(N * logK),空间 O(K)。当 K << N 时远优于排序(O(N*logN))。
其他方案:快速选择算法(QuickSelect)平均 O(N),最坏 O(N^2)。适合一次性找第 K 大且不需要排序结果的场景。