有一个数组,找出其中数量超过的元素是谁。比如数组 [3, 2, 3]
,输出 3。
这个问题要解起来不难,暴力计数,转为 map,排序都能解决。但是他们的空间复杂度都不低,即便排序能做到 O(1) 的空间复杂度,但最低的时间复杂度也是 O(nlogn)。
还有一种叫 Boyer-Moore 投票算法,时间复杂度 O(n),空间复杂度 O(1)。它的思路类似于消消乐,我们将超过一半的数叫做众数,先将数组分成众数和其他数两个阵营,然后一一相消,剩下的就是众数了。
- 如果 count = 0,将 value 设置为 x,count 设置为 1;
- 否则判断 x 与 value 是否相等:
- 如果 x = value,count 加一;
- 否则 count 减一。
在 elixir 中我们可以用 reduce 来实现这个迭代过程。
defmodule Solution do
@spec majority_element(nums :: [integer]) :: integer
def majority_element(nums) do
nums
|> Enum.reduce({0, 0}, fn
x, {_, 0} -> {x, 1}
x, {x, n} -> {x, n+1}
_, {m, n} -> {m, n-1}
end)
|> elem(0)
end
end