题目
1. 排序
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
2. 遍历判断
- 随机找
class Solution { public: int majorityElement(vector<int>& nums) { while (true) { int ans = nums[rand() % nums.size()]; // 随即找 int cnt = count(nums.begin(), nums.end(), ans); // 判断是不是众数 if (cnt > nums.size() / 2) return ans; } return -1; } };
- 头尾找
class Solution { public: int majorityElement(vector<int>& nums) { int left = 0; int right = nums.size() - 1; while(left <= right) { if(count(nums.begin(), nums.end(), nums[left]) > nums.size() / 2) return nums[left]; if(count(nums.begin(), nums.end(), nums[right]) > nums.size() / 2) return nums[right]; left++; right--; } return 0; } };
3. 哈希表
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> counts;
for (int num: nums) {
++counts[num];
if (counts[num] > nums.size() / 2)
return num;
}
return 0;
}
};
4. 分治
总区间的众数一定是某个子区间的众数,因此只需判断划分后的子区间的哪一个众数满足条件即可。
class Solution {
public:
int rec(vector<int>& nums, int low, int high) {
if (low == high)
return nums[low];
int mid = (low + high) / 2;
int left = rec(nums, low, mid);
int right = rec(nums, mid + 1, high);
if (count(nums.begin() + low, nums.begin() + high + 1, left) > (high - low + 1) / 2)
return left;
if (count(nums.begin() + low, nums.begin() + high + 1, right) > (high - low + 1) / 2)
return right;
return -1;
}
int majorityElement(vector<int>& nums) {
return rec(nums, 0, nums.size() - 1);
}
};
5. Boyer-Moore 投票算法
维护一个候选众数candidate
和它出现的次数count
,初始时candidate
可以为任意值,count
为0。
我们遍历数组nums
中的所有元素,对于每个元素x
,在判断x
之前,如果count
的值为0,我们先将x
的值赋予candidate
,随后我们判断x
:
- 如果
x
与candidate
相等,那么计数器count
的值增加1 - 如果
x
与candidate
不等,那么计数器count
的值减少1
在遍历完成后,candidate
即为整个数组的众数。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int candidate = -1;
int count = 0;
for (int num : nums) {
if (num == candidate)
++count;
else if (--count < 0) {
candidate = num;
count = 1;
}
}
return candidate;
}
};