给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
此题与上一题 LeetCode 求众数
就是这题众数的定义是出现超过 ⌊ n/3 ⌋ 次的。并且要求空间复杂度为O(1),所以不能使用map进行标记。只能使用上一题的方法二。因为这里的众数出现超过 ⌊ n/3 ⌋ 次,所以最多只有两个众数。使用两个不同的士兵镇守两个阵地即可。
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> res;
//两个士兵分别镇守两个阵地
int one = 0, two = 0, cntOne = 0, cntTwo = 0;
for (auto &num : nums) {
if (num == one) {//第一个士兵遇到友军
++cntOne;
}
else if (num == two) {//第二个士兵遇到友军
++cntTwo;
}
else if (cntOne == 0) {//第一个阵地士兵全部阵亡,更换镇守的士兵
one = num, cntOne = 1;
}
else if (cntTwo == 0) {//第二个阵地士兵全部阵亡,更换镇守的士兵
two = num, cntTwo = 1;
}
else {//否则,两个阵地都必须牺牲一名士兵
--cntOne, --cntTwo;
}
}
cntOne = cntTwo = 0;
//再次遍历数组,验证是否是众数
for (auto &num : nums) {
if (num == one) {
++cntOne;
}
else if (num == two) {
++cntTwo;
}
}
if (cntOne > nums.size() / 3) {
res.push_back(one);
}
if (cntTwo > nums.size() / 3) {
res.push_back(two);
}
return res;
}
};