题目描述
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋
次的元素。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
解题思路
由于数组中出现次数超过 $frac{1}{3}$ 的数字最多只可能为两个,所以记录两个数字n1、n2,以及他们出现的次数c1、c2,遍历数组并做以下操作:
- 若当前两数字出现则把对应的次数加1;
- 若其中一个出现次数为0,则把当前数字赋给出现次数为0的数字,并将其出现次数置为1;
- 若当前数字不同于任何一个数字,则将两数字的出现次数都减1
最后得到两个数字以及他们出现的次数,再遍历一遍数组记录他们的出现次数,若大于 $frac{n}{3}$ 则加入到结果中。
代码
1 class Solution { 2 public: 3 vector<int> majorityElement(vector<int>& nums) { 4 vector<int> res; 5 if(nums.empty()) return res; 6 int n1 = nums[0], n2 = 0, c1 = 1, c2 = 0; 7 for(int i = 1; i < nums.size(); i++){ 8 if(nums[i] == n1) c1++; 9 else if(nums[i] == n2) c2++; 10 else if(c1 == 0){ 11 n1 = nums[i]; 12 c1++; 13 } 14 else if(c2 == 0){ 15 n2 = nums[i]; 16 c2++; 17 } 18 else{ 19 c1--; 20 c2--; 21 } 22 } 23 c1 = c2 = 0; 24 for(int i = 0; i < nums.size(); i++){ 25 if(nums[i] == n1) c1++; 26 else if(nums[i] == n2) c2++; 27 } 28 if(c1 > nums.size() / 3) res.push_back(n1); 29 if(c2 > nums.size() / 3) res.push_back(n2); 30 return res; 31 } 32 };