题意
给一个数组,求它的majority,对majority的定义为:出现次数超过⌊n2⌋的元素。
思路
算法1
O(nlogn)时间。
排序,然后返回中间的那个元素即可。
算法2
O(n)时间和O(n)空间。
我们用unordered_map来存储每个元素出现的次数,最后返回出现次数超过⌊n2⌋的元素即可。
算法3
我们能否将空间继续优化到const呢?答案是肯定的。
假设我们令我们的majority元素的数目为y,其他元素的个数为x,因为y>⌊n2⌋。所以,一定有y−x>0。也就是说:平均情况下,至少每两个数会出现一个y。
那么,我们可以用一个cnt来记录y出现的次数,但是此时我们并不知道y是多少?那么我们假设任意一个元素z为我们的majority,然后此时的cnt记为1。然后继续去遍历数组,假设当前遇到的元素为
- 如果x=z: cnt++
- 如果x≠z: cnt–: 当我们发现cnt为-1的时候,说明在目前长度下,z并不是我们的majority。那么用x去替换z。
最后得到的z就是我们的majority。
然后刚刚查了一下,发现这个算法叫做Moore投票算法。
代码
//algorithm 1
class Solution {
public:
int majorityElement(vector<int>& nums) {
//O(nlogn) time
sort(nums.begin(), nums.end());
//the begin position is 0, so don't need to add 1
return nums[nums.size() >> 1];
}
};
//algorithm 2
//O(n) time and O(n) space
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> count;
for (auto x : nums) {
count[x]++;
//more than floor(n / 2), so should >
if (count[x] > (nums.size() >> 1)) return x;
}
return 0;
}
};
//algorithm 3
//O(n) time and O(1) space
class Solution {
public:
int majorityElement(vector<int>& nums) {
int cnt = 0, y = nums[0];
for (auto x : nums) {
if (x == y) cnt++;
else {
cnt--;
if (cnt == -1) y = x, cnt = 1;
}
}
return y;
}
};

&spm=1001.2101.3001.5002&articleId=55224452&d=1&t=3&u=4786ace025874f468e452e3ec12b96e6)
646

被折叠的 条评论
为什么被折叠?



