对手方活跃度漂移:跨两段成交流水的最大计数差异
Counterparty Activity Shift: Largest Trade-Count Differential Across Two Sessions
开始编码实现 solution(stream_a: list[int], stream_b: list[int]) -> int。两个列表分别是两段交易时段的对手方 ID 流水——按到达顺序记录,每次成交对应一个整数,重复出现是常态(一个对手方在一段里成交两次就在该段列表里出现两次)。对每个在任一流中出现过的对手方 cp,计算其绝对成交次数差:
diff(cp) = | freq_a[cp] - freq_b[cp] |其中 freq_a[cp] 为 cp 在 stream_a 中出现的次数(不出现时计为零),freq_b[cp] 同理。返回使 diff(cp) 最大的整数 cp。diff 同分时取最小的 cp id。若两条流都为空,返回 -1。
例
solution([7, 3, 7, 5, 3, 3], [7, 7, 7, 5, 5, 9]) 返回 3。计数:A 中 7 出现 2 次、3 出现 3 次、5 出现 1 次;B 中 7 出现 3 次、5 出现 2 次、9 出现 1 次。差值:cp 7 -> |2-3| = 1、cp 3 -> |3-0| = 3(仅 A)、cp 5 -> |1-2| = 1、cp 9 -> |0-1| = 1。最大值 3 由 cp 3 取得,因此答案为 3。注意 cp 3 "仅在 A 出现"——它在 B 中的计数隐式为 0,差值就等于它在 A 中的频次。
同分示例。solution([1, 1, 2, 2, 3], []) 返回 1。B 为空,每个 cp 的差值就等于其在 A 中的频次:cp 1 -> 2、cp 2 -> 2、cp 3 -> 1。cp 1 与 cp 2 同分在 2,按"取较小 cp id"的规则输出 1(而非 2)。
几个边界细节。solution([], []) 返回 -1——这是唯一的哨兵路径。仅一侧为空不走哨兵:缺失那侧的计数全部隐式为 0,常规逻辑就能正确给出答案。当所有 cp 都满足 freq_a[cp] == freq_b[cp](差值全 0)时,所有 cp 同分在 0,答案是并集中最小的 cp,也不是 -1。约束 cp_id >= 0 保证负数不会作为合法 cp 出现,因此 -1 哨兵不会与任何真实 cp 撞码。
预期算法:对两条流各做一遍 dict 计数,然后对键的并集做一次遍历,按字典序 (-diff, cp) 维护当前最优 (diff, cp) 对。总耗时 O(N + M),空间 O(D),其中 D 为两条流并集后的去重 cp 数。
实现细节由 stubs/stub.py 提供。
实践背景
一个收盘后的交易后端运维仪表板会比对相邻两段时段的对手方流水——例如上午连续竞价段 A 与下午连续竞价段 B——并问:哪一个对手方在两段之间的"活跃度"漂移最大?此处的"活跃度"指笔数漂移,把每一笔成交都当作该对手方的一次心跳,与规模、买卖方向无关。一个上午频繁交易、下午突然沉寂(或反过来)的对手方,正是运维侧最先关注的"时段间活跃度异常"信号——突然沉寂可能是连接故障,突然爆发可能是库存调整或竞争对手切回了攻击性策略。指标取绝对差而非有符号差,是因为仪表板只关心变化幅度;变化方向(A 多还是 B 多)会另行从原始计数中读取。同分时取最小 cp 是为了让"漂移最大对手方"这一行在多次重跑下保持字节一致,避免 tiebreak 偶发翻转污染"今天与昨天报告 diff"。双流并集模式 set(freq_a) | set(freq_b) + 每边 .get(cp, 0) 是后端聚合的标准书写法,向 N 流以及加权变体(按方向计数、按合约计数等)扩展时无需改动外层骨架。
约束条件
- 0 <= len(stream_a), len(stream_b) <= 5000
- 每个 cp_id 满足 0 <= cp_id <= 10**6
- 两条流都为空时返回 -1(哨兵;因 cp_id >= 0,-1 与任何真实 cp 都不会撞码)
- 若至少一条流非空,输出为使 |freq_a[cp] - freq_b[cp]| 最大的 cp,同分取最小 cp_id
- 返回类型为 int(非负 cp_id 或 -1 哨兵)
样例
Case 1 · statement-example: cp 3 only in A wins with diff 3
输入: [[7,3,7,5,3,3],[7,7,7,5,5,9]]
期望: 3
A 计数 {7:2,3:3,5:1};B 计数 {7:3,5:2,9:1}。差值:cp 7→1, cp 3→3, cp 5→1, cp 9→1。最大 3,对应 cp 3。
Case 2 · statement-example: B empty, tie at diff 2 -> smallest cp 1
输入: [[1,1,2,2,3],[]]
期望: 1
B 为空,差值=A 频次:cp 1→2, cp 2→2, cp 3→1。cp 1 与 cp 2 同分在 2,取较小 cp 1。
Case 3 · statement-example: both streams empty -> sentinel -1
输入: [[],[]]
期望: -1
两条流都为空,按规则返回哨兵 -1。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: cp 3 only in A wins with diff 3
输入: [[7,3,7,5,3,3],[7,7,7,5,5,9]]
期望: 3
A 计数 {7:2,3:3,5:1};B 计数 {7:3,5:2,9:1}。差值:cp 7→1, cp 3→3, cp 5→1, cp 9→1。最大 3,对应 cp 3。
Case 2 · statement-example: B empty, tie at diff 2 -> smallest cp 1
输入: [[1,1,2,2,3],[]]
期望: 1
B 为空,差值=A 频次:cp 1→2, cp 2→2, cp 3→1。cp 1 与 cp 2 同分在 2,取较小 cp 1。
Case 3 · statement-example: both streams empty -> sentinel -1
输入: [[],[]]
期望: -1
两条流都为空,按规则返回哨兵 -1。