本文主要是介绍第二十一章:数组中超过出现次数超过一半的数字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第二十一章数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
//题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
#include <iostream>
#include <vector>
#include <hash_map> using namespace std; //第一种方法
//hash法,时间O(n),空间O(n)
int Find(int *a,int N){hash_map<int,int> hm;int candidate;int maxTimes=INT_MIN;for(int i=0;i<N;i++){hm[a[i]]++;if(hm[a[i]]>maxTimes){maxTimes=hm[a[i]];candidate=a[i];}}return candidate;
}//第二种方法
//统计法,时间O(n),空间O(1)
int Find2(int *a, int N) //a代表数组,N代表数组长度
{ int candidate; int nTimes, i; for(i = nTimes = 0; i < N; i++) { if(nTimes == 0) { candidate = a[i], nTimes = 1; } else { if(candidate == a[i]) nTimes++; else nTimes--; } } return candidate;
} //第三种方法
//删除法,因为涉及到删除,数组不好操作,所以用容器处理
int Find3(int *a,int N) //a代表数组,N代表数组长度
{ vector<int> num(a,a+N);for(auto it=num.begin();it!=num.end();){auto n=next(it);for(;n!=num.end()&&n==it;++n);if(n==num.end())break;num.erase(n);it=num.erase(it);}return *num.begin();
}
int main()
{ int a[]={4,5,6,5,5,4,7,5,5};cout<<Find3(a,sizeof(a)/sizeof(int))<<endl;
}
加强版水王:找出出现次数刚好是一半的数字
//题目:找出出现次数刚好是一半的数字
#include <iostream>
#include <vector>
#include <hash_map> using namespace std; //第一种方法
//统计法,时间O(n),空间O(1)
//将不看数组的最后一个元素,先将问题转化成了超过一半的数处理
//最后一个元素无外乎两种情况,一种是最后一个元素不是这等于一半的数,那就不予考虑,以上得出的即是答案
//最后一个元素即是这等于一半的数,上面得出的就不一定是解,那就统计该元素出现的次数
int Find(int *a, int N) //a代表数组,N代表数组长度
{ int candidate; int nTimes, i; for(i = nTimes = 0; i < N; i++) { if(nTimes == 0) { candidate = a[i], nTimes = 1; } else { if(candidate == a[i]) nTimes++; else nTimes--; } } int cnt=0;for(int i=0;i<N;i++)if(a[i]==candidate)cnt++;return cnt==N/2?candidate:a[N-1];
} //第二种方法
//两个变量记录法
int Find2(int *a,int N){int candidate1,candidate2; int nTimes1, nTimes2, i; for(i = nTimes1 = nTimes2 =0; i < N; i++) { if(nTimes1 == 0) { candidate1 = a[i], nTimes1 = 1; } else if(nTimes2 == 0 && candidate1 != a[i]) //注意:这里的判断条件加上第二个变量是否等于第一个变量的判断 { candidate2 = a[i], nTimes2 = 1; } else { if(candidate1 == a[i]) nTimes1++; else if(candidate2 == a[i]) nTimes2++; else { nTimes1--; nTimes2--; } } } return nTimes1>nTimes2?candidate1:candidate2;
}
int main()
{ int a[]={7,5,6,5,5,7,7,5};cout<<Find2(a,sizeof(a)/sizeof(int))<<endl;
}
这篇关于第二十一章:数组中超过出现次数超过一半的数字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!