← 返回编程题库
coding-find-third-largest-distinct简单免费版2000ms未尝试

查找第三大的不同元素

Find Third Largest Distinct

开始编码

给一个整数数组 nums,长度 N1 ≤ N ≤ 10⁴,每个 nums[i] ∈ [-10⁹, 10⁹])。返回 nums第三大的不同值。这就是经典 LeetCode 414:「第三大」是按不同值集合算的,不是按位置算的,所以重复元素先合并再排名。如果 nums 里少于三个不同值,按规则返回最大值作为兜底。

干净的做法是一次线性扫描,维护三个可选标量 a, b, c 表示见过的前三大不同值(一开始都为 None),不变量 a > b > c(填满时)。对每个 x:如果 x 已经等于 a, b, c 之一就跳过(与现有槽重复);否则按大小插入合适的槽,并把更小的标量整体下移。扫完后,若 c is None,说明只见过不到三个不同值——返回 a(最大值);否则返回 c。时间 O(n),额外空间 O(1),不用建 sorted(set(nums)) 这种辅助列表。

Examples

solution([3, 2, 1]) 返回 1。不同值集合是 {1, 2, 3},降序排列是 [3, 2, 1],第三大是 1。三标量扫一遍:吃 3a=3;吃 2a=3, b=2;吃 1a=3, b=2, c=1。槽 c 已填,返回 1

solution([1, 2]) 返回 2。只有两个不同值,少于三个,按规则退化返回最大值 2。扫完后 a=2, b=1, c=None,触发 c is None 兜底,返回 a

solution([2, 2, 3, 1]) 返回 1。这就是「重复元素陷阱」的典型:按位置降序排是 [3, 2, 2, 1],第三个位置上是 2;但按不同值集合 {1, 2, 3} 降序是 [3, 2, 1],第三大是 1。三标量循环里那个跳过重复的分支会忽略第二个 2,最终返回 1,符合 LeetCode 414 的「distinct 而非 positional」定义。

签名见 stubs/stub.py

Practical context

「带去重的 Top-K」直接出现在微观结构信号筛选里:某一时刻你手里有几百个候选 alpha 信号(残差动量分、队列失衡比、跨品种领先滞后 z-score),但资金只够压注其中最强的 K 个互不冗余的信号。两个数值得分完全相同的信号,往往是同一个底层视角被两条 pipeline 重复算出来——把它们当成两个独立的 Top-K 项,等于把同一个赌注下了两次。先按不同值排名,再把每个保留的名次映射回一个代表信号,可以避免这种双重计算。这道题用的「三标量单遍扫」,以及它在任意 K 上的推广(大小为 K 的小顶堆 + 旁路一个「已见值集合」来强制 distinct),就是 Top-K 信息流排序、Top-K 排行榜切分、Top-K 最活跃标的看板、流式撮合行情中 Top-K 最大簿口失衡扫描背后的同一个形状。一句话:当任何信号聚合场景出现「第三大」或「Top K」字样,先问一句「重复值要不要合并」——几乎一定要合,三标量 / 大小 K 堆 这个模式就给你 O(n) 时间内的正确语义,而无需做完整排序。

约束条件

  • 1 ≤ N ≤ 10^4,N = len(nums)
  • -10^9 ≤ nums[i] ≤ 10^9
  • 返回第三大的不同值;若不同值少于 3 个,返回最大值

样例

Case 1 · typical: three strictly decreasing distinct values

输入: [[3,2,1]]

期望: 1

数组里恰好有 3 个不同的值 {3, 2, 1},从大到小排序就是 3 > 2 > 1,第三大(distinct)就是 1。三标量法扫一遍:先吃 3 → a=3;再吃 2 → a=3, b=2;再吃 1 → a=3, b=2, c=1。c 已填满,返回 c=1。

Case 2 · fewer-than-3-distinct: only two distinct values, fall back to max

输入: [[1,2]]

期望: 2

只有两个不同的值,少于 3 个,所以按规则退化为返回最大值 max=2。三标量法扫完后 c 仍为 None,触发兜底分支返回 a=2。

Case 3 · with-duplicates: 3 distinct after dedup

输入: [[2,2,3,1]]

期望: 1

出现两个 2,但 distinct 视角下集合是 {1, 2, 3},从大到小是 3 > 2 > 1,第三大是 1。注意不是「按位置数第三」(那会返回 3),是「不同值里数第三」。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · typical: three strictly decreasing distinct values

输入: [[3,2,1]]

期望: 1

数组里恰好有 3 个不同的值 {3, 2, 1},从大到小排序就是 3 > 2 > 1,第三大(distinct)就是 1。三标量法扫一遍:先吃 3 → a=3;再吃 2 → a=3, b=2;再吃 1 → a=3, b=2, c=1。c 已填满,返回 c=1。

Case 2 · fewer-than-3-distinct: only two distinct values, fall back to max

输入: [[1,2]]

期望: 2

只有两个不同的值,少于 3 个,所以按规则退化为返回最大值 max=2。三标量法扫完后 c 仍为 None,触发兜底分支返回 a=2。

Case 3 · with-duplicates: 3 distinct after dedup

输入: [[2,2,3,1]]

期望: 1

出现两个 2,但 distinct 视角下集合是 {1, 2, 3},从大到小是 3 > 2 > 1,第三大是 1。注意不是「按位置数第三」(那会返回 3),是「不同值里数第三」。