原题
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2限制:
- 1 <= 数组长度 <= 50000
思路
因为题目给定了数组总是存在多数元素,所以这题利用 摩尔投票法 即可解决。
首先给个暴力的解法:
暴力
- C++
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> mp;
for (auto &num : nums) {
++mp[num];
}
int size = nums.size();
for (auto &it : mp) {
if (it.second > size / 2) {
return it.first;
}
}
return -1;
}
};
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( N ) O(N) O(N) 用到了哈希表。
摩尔投票法
不同抵消,如果是多数元素,投票数肯定不会为0的。
- C++
class Solution {
public:
int majorityElement(vector<int>& nums) {
// 假设nums[0]是多数元素
int mode = nums[0];
// 记录多数元素的个数
int vote = 1;
int size = nums.size();
for (int i = 1; i < size; ++i) {
// 如果票数为0,说明假设的这个元素不是多数元素
if (vote == 0) {
// 继续假设当前这个数是多数元素
vote = 1;
mode = nums[i];
} else {
// 如果当前数字等于假设的多数元素, 投一票
if (mode == nums[i]) {
++vote;
} else {
--vote;
}
}
}
return mode;
}
};
- Python
class Solution:
def majorityElement(self, nums: List[int]) -> int:
mode, vote = nums[0], 1
size = len(nums)
for i in range(1, size):
if vote == 0:
vote = 1
mode = nums[i]
else:
if nums[i] == mode:
vote += 1
else:
vote -= 1
return mode
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( 1 ) O(1) O(1)
相似的题:面试题 17.10. 主要元素