Majority Element II[medium]
Description
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.
Solution
这道题目是Majority Element的升级版,上一次是寻找大于n/2次,这一次是寻找n/3次,我们同样可以利用上次的方法在线性时间,O(1)空间完成,只需要使用Map结果。
vector<int> result;
map<int, int> record;
int l = nums.size()/3;
int val = 0;
for (auto iter = nums.begin(); iter != nums.end(); iter++) {
record[*iter]++;
if (record[*iter] > l ) {
if (result.empty() || ((result[0] != *iter)&&result.size()!= 2)) {
result.push_back(*iter);
}
}
}
return result;
那是否有不使用Map的方法来达到目的呢?
- 如果有一个数在数组中出现超过n/3次,我们不难判断在这个数组中这样的数至多有两个,否则矛盾。
进而我们可以假设,如果将这组数分为若干组,每组有3个,那么出现超过n/3次的数肯定在其中一个组出现过两次
根据以上情况,我选择使用摩尔投票法。“摩尔投票法的基本思想很简单,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。”(这是对于超过n/2次的情况,我们可以类比)
class Solution { public: vector<int> majorityElement(vector<int>& nums) { vector<int> result; int n = nums.size(); int num1, num2, count1, count2; count1 = 0; count2 = 0; for (int i = 0; i < n; i++) { if (num1 == nums[i]) { count1++; } else if (num2 == nums[i]) { count2++; } else if (count1 == 0) { num1 = nums[i]; count1++; } else if (count2 == 0) { num2 = nums[i]; count2++; } else { count1--; count2--; } } count1 = count2 = 0; for (int i = 0; i < n; i++) { if (nums[i] == num1) count1++; if (nums[i] == num2) count2++; } if (num1 == num2) { if (count1 > n/3) result.push_back(num1); } else { if (count1 > n/3) result.push_back(num1); if (count2 > n/3) result.push_back(num2); } return result; } };