题目
Boyer-Moore 投票算法
思路
摩尔投票法,遇到相同的数,就投一票,遇到不同的数,就减一票,最后还存在票的数就是众数。
复杂度分析
O(n)
实现
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;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
哈希表解法
思路
遍历一遍数组,维护一个哈希表充当计数器,元素每出现一次,对应计数器+1,如果某个元素出现次数>数组长度的一半。
复杂度分析
O(n)
实现
class Solution {
public:
int majorityElement(vector<int>& nums) {
int size = nums.size();
map<int,int> hash;
for(int i : nums) {
hash[i]++;
if(hash[i]>size/2) return i;
}
return 0;
}
};
其它解法
分治法
将原数组划分成更小的区间找出各自众数,众数间再互相pk,决定最后的众数。时间复杂度O(nlogn)
。
实现
class Solution {
int count_in_range(vector<int>& nums, int target, int lo, int hi) {
int count = 0;
for (int i = lo; i <= hi; ++i)
if (nums[i] == target)
++count;
return count;
}
int majority_element_rec(vector<int>& nums, int lo, int hi) {
if (lo == hi)
return nums[lo];
int mid = (lo + hi) / 2;
int left_majority = majority_element_rec(nums, lo, mid);
int right_majority = majority_element_rec(nums, mid + 1, hi);
if (count_in_range(nums, left_majority, lo, hi) > (hi - lo + 1) / 2)
return left_majority;
if (count_in_range(nums, right_majority, lo, hi) > (hi - lo + 1) / 2)
return right_majority;
return -1;
}
public:
int majorityElement(vector<int>& nums) {
return majority_element_rec(nums, 0, nums.size() - 1);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
排序法
排序后众数在n/2的位置。复杂O(nlogn)
随机算法
随便选个数,计算它出现的次数,如果不是,再换一个。这个算法理论上的时间复杂度是线性的。