# 数组中出现次数超过数组长度一半的数字
# 一、题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000
# 二、解题思路
- 哈希表统计法: 遍历数组
nums
,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N)。
/**
* @param {number[]} nums
* @return {number}
*/
var majorityElement = function(nums) {
if (nums.length === 0) return -1;
if (nums.length === 1) return nums[0];
let map = new Map(); // {值:次数}
for (let i = 0; i < nums.length; i++) {
let value = nums[i];
if (map.has(value)) {
let count = map.get(value);
if ((count + 1) * 2 > nums.length) return value;
map.set(value, count+1);
} else {
map.set(value, 1);
}
}
return -1;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 数组排序法: 将数组
nums
排序,数组中点的元素 一定为众数。
/**
* @param {number[]} nums
* @return {number}
*/
var majorityElement = function(nums) {
if (nums.length === 0) return -1;
if (nums.length === 1) return nums[0];
nums.sort((a,b) => a - b);
return nums[parseInt(nums.length / 2)];
};
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 摩尔投票法:核心理念为 票数正负抵消 。此方法时间和空间复杂度分别为 O(N) 和 O(1) ,为本题的最佳解法。
/**
* @param {number[]} nums
* @return {number}
*/
var majorityElement = function(nums) {
if (nums.length === 0) return -1;
if (nums.length === 1) return nums[0];
let votes = 0;
let x = 0;
for (let i = 0; i < nums.length; i++) {
if (votes === 0) x = nums[i];
votes += x === nums[i] ? 1 : -1;
}
return x;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16