#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <set>
#include <unordered_map>
using namespace std;
/*
问题:
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.
分析:寻找向下取整,出现次数>=n/3的那个数字,只允许在O(n)时间,
空间O(1)范围内。之前求发帖超过一半的人,利用计数器来做。
这里应该也可以设计两个计数器变量:coun1,count2。
如果仅仅是与当前数不同就相减,会造成计数器变成负数,显然不能这么做。
难道是每遇到3个不同的就减去1不就可以了,至多有3个这样的变量
等于当前一个计数器变量等于3次。
输入:
9
1 2 3 4 1 2 3 1 1
9
1 2 4 4 4 4 1 1 1
10
1 2 3 4 1 2 3 1 4 5
1
1
9
1 2 3 1 2 3 1 2 3
2
1 2
3
1 2 3
3
1 2 2
输出:
1
1 4
no result
1
no result
1 2
no result
2
关键:
1 题目说要大于n/3,其实最大的数最多为两个,我错误得认为是3个,看错题目条件
2 套用最大的数的解法,令初始的数为LONG_MAX,即取不到的值,然后让当前元素和这个元素比较,
这个就是用于后续更新元素【厉害】
3
元素相等:累加
次数为0:重新选择带比较元素
否择,既非相等,又非替换:累减
而且次数为0,只会按照优先更新的次序,而不是一起更新【厉害】,这样才不会出现一样的结果
4得到的value1或value2还不一定都是,还需要验证次数,因此需要之前一个哈希map存储值到出现次数的映射
*/
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> result;
if(nums.empty())
{
return result;
}
long long value1 , value2 ;
value1 = value2 = ULONG_MAX;
int count1 = 0;
int count2 = 0;
int size = nums.size();
unordered_map<int , int> valueToTimes;
for(int i = 0 ; i < size ; i++)
{
//如果元素出现过
if(valueToTimes.find(nums.at(i)) != valueToTimes.end())
{
valueToTimes[nums.at(i)]++;
}
else
{
valueToTimes[nums.at(i)] = 1;
}
//先判断是否元素相同
if(nums.at(i) == value1)
{
count1++;
}
else if(nums.at(i) == value2)
{
count2++;
}
//再判断是否需要更新
else if(0 == count1)
{
value1 = nums.at(i);
count1 = 1;
}
else if(0 == count2)
{
value2 = nums.at(i);
count2 = 1;
}
//进行累减
else
{
count1--;
count2--;
}
}
//得到的value1或value2还不一定都是,还需要验证次数,因此需要之前一个哈希map存储
if(count1 > 0)
{
if(valueToTimes[value1] > (size / 3))
{
result.push_back(value1);
}
}
if(count2 > 0)
{
if(valueToTimes[value2] > (size / 3))
{
result.push_back(value2);
}
}
return result;
}
};
void print(vector<int>& result)
{
if(result.empty())
{
cout << "no result" << endl;
return;
}
int size = result.size();
for(int i = 0 ; i < size ; i++)
{
cout << result.at(i) << " " ;
}
cout << endl;
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
while(cin >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
result = solution.majorityElement(nums);
print(result);
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
/*
vector<int> majorityElement(vector<int>& nums) {
vector<int> result;
if(nums.empty())
{
return result;
}
int size = nums.size();
//只有1个元素,肯定是
unordered_map<int ,bool> visited;
if(size <= 3)
{
for(int i = 0 ; i < size ; i++)
{
if(visited.find(nums.at(i)) == visited.end())
{
visited[nums.at(i)] = true;
result.push_back(nums.at(i));
}
}
return result;
}
int count1 = 3;
int count2 = 3;
int count3 = 3;
int value1 = nums.at(0);
int value2 = nums.at(1);
int value3 = nums.at(2);
//计算count1,在第1~3元素后的结果值
if(value1 == value2 )
{
// v1 = v2 = v3
if(value1 == value3){
count1 += 6;
count2 += 6;
count3 += 6;
}//v1 = v2 != v3
else{
count1 += 2;
count2 += 2;
count3 -= 2;
}
}// v1 != v2
else{
//v1 = v3 != v2
if(value1 == value3){
count1 += 2;
count2 -= 2;
count3 += 2;
}
//v1 != v3, v1 != v2
else
{
count1 -= 2;
if(value2 == value3){
count2 += 2;
count3 += 2;
}else{
count2 -= 2;
count3 -= 2;
}
}
}
for(int i = 3 ; i < size ; i++ )
{
if(value1 != nums.at(i)){
count1--;
}else{
count1 += 3;
}
//直到减为0,说明一个数抵掉三个数了,才更新
if(0 == count1){
value1 = nums.at(i);
count1 = 3;
}
if(value2 != nums.at(i))
{
count2--;
}else{
count2 += 3;
}
if(0 == count2){
value2 = nums.at(i);
count2 = 3;
}
if(value3 != nums.at(i)){
count3--;
}else{
count3 += 3;
}
if(0 == count3){
value3 = nums.at(i);
count3 = 3;
}
}
if(count1 > 0)
{
result.push_back(value1);
}
if(count2 > 0)
{
result.push_back(value2);
}
if(count3 > 0)
{
result.push_back(value3);
}
return result;
}
*/
leecode 解题总结:229. Majority Element II
最新推荐文章于 2021-07-09 11:05:07 发布