Leetcode169. 多数元素
题目:
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于
⌊
n
/
2
⌋
⌊ n/2 ⌋
⌊n/2⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
题解:
方案一:hash表方式,额外定义一个hashmap,key为每个元素值,value为每个元素的个数,找到最大的value对应的key即可。
- 时间复杂度:O(n)
- 空间复杂度:O(n)
方案二:排序,位置在n/2的值即为众数。
- 时间复杂度:O(nlgn)
用 Python 和 Java 将数组排序开销都为 O(nlgn) ,它占据了运行的主要时间。 - 空间复杂度:O(1) 或者 O(n)
我们将 nums 就地排序,如果不能就地排序,我们必须使用线性空间将 nums 数组拷贝,然后再排序。
方案三: Boyer-Moore 投票算法。如果我们把众数记为 +1 ,把其他数记为 −1 ,将它们全部加起来,显然和大于 0 ,从结果本身我们可以看出众数比其他数多。
- 时间复杂度:O(n)
Boyer-Moore 算法严格执行了 n 次循环,所以时间复杂度是线性时间的。 - 空间复杂度:O(1)
Boyer-Moore 只需要常数级别的额外空间。
scala代码如下:
hash表方式:
def majorityElement(nums: Array[Int]): Int = {
val map = new util.HashMap[Int, Int]()
for (num <- nums) {
val i = map.getOrDefault(num, 0)
map.put(num, i + 1)
}
val keySet: util.Set[Int] = map.keySet()
var maxKey = 0
var maxValue = 0
val it = keySet.iterator()
while (it.hasNext) {
val key = it.next()
if (map.get(key) > maxValue) {
maxKey = key
maxValue = map.get(key)
}
}
maxKey
}
排序方式:
def majorityElement2(nums: Array[Int]): Int = {
java.util.Arrays.sort(nums)
nums(nums.length / 2)
}
Boyer-Moore 投票算法:
def majorityElement3(nums: Array[Int]): Int = {
var count = 0
var candidate = 0
for (num <- nums) {
if (count == 0) {
candidate = num
}
if (num == candidate) {
count = count + 1
} else {
count = count - 1
}
}
candidate
}