【竞赛】查找整型数组里出现频率最高的数字的算法

老紫竹 2009-02-24 04:47:49
加精
从n个整数中查找出现频率最高的所有整数(用java实现)
示例:5,5,8,5,3,5,3,3,3,1
中出现频率最高的整数是3和5

提示:

方案1,最少的内存占用
方案2,最快的速度,不考虑内存

注意,数据中可能包含负数,比如
5,5,8,5,-3,5,-3,-3,-3,1
这类情况也要处理。


提供一个标准的数据提供程序,大家可以用这个做基准

private static int[] getdata() {
int NUMBER = 10000000;
int[] arr = new int[NUMBER];
Random ran = new Random(20090228);
int sign = -1;
for (int i = 0; i < NUMBER; i++) {
sign *= -1;
arr[i] = sign * ran.nextInt(NUMBER);
}
return arr;
}

生成1000万个随机数字,答案为
-9759534,-8687158,-6558899,-3713417,-2969181,-2684019,-950275,-274364,102097,2588019,4580505,4787470,5706388,6278099,6386057,8380143,8683339,9537038,出现次数为7
用时为:XXXX


这个时间,大家就自己考虑吧。因为每个人的机器不同,请直接提供你本地测试最快的,以及占用内存最少的就行了。


补充:
计数法对于那些数据量不是很大,但数据差异非常大的,并不适合,比如

{Integer.MIN_VALUE,1,Integer.MAX_VALUE}
类似这样的,呵呵,所以还是寻找一个更通用的解决方案。

特别是,如果数据是Long.MAX_VALUE怎么办!


...全文
3456 170 打赏 收藏 转发到动态 举报
写回复
用AI写文章
170 条回复
切换为时间正序
请发表友善的回复…
发表回复
niansiqiao 2011-01-03
  • 打赏
  • 举报
回复
一个时间复杂度为O(n),空间复杂度为O(n)的算法(摘自Java程序员职场全攻略P82)
主要思想: 首先构造散列表,把字符串生成的数组中每个元素当作要存放的值。新建一个哈希表,长度为数组的长度,这样能保证存下整个数组。随便定义一个哈希函数,比如h(x)=x%length, length为哈希表的长度。
然后进行存储,把数组中的每个数都通过哈希函数计算出地址,如果地址冲突,就判断待存数是否与已存在数相同,不相同则根据处理冲突方法继续寻找散列地址,相同则计数器加1。
最后先遍历出最大值max再把所有与最大值max相等的字符输出即可。
不过好像这样数组中有负数的不能处理
enlonely 2009-03-18
  • 打赏
  • 举报
回复
收了,慢慢理解。。
wclszh 2009-03-18
  • 打赏
  • 举报
回复
学习
  • 打赏
  • 举报
回复
用了hashmap的特性,应该不符合要求,只是娱乐而已

HashMap hm=new HashMap();
HashMap hmres=new HashMap();
int t_sum=5;

private static int[] getdata() {
int NUMBER = 1000000;
int[] arr = new int[NUMBER];
Random ran = new Random(20090228);
int sign = -1;
for (int i = 0; i < NUMBER; i++) {
sign *= -1;
arr[i] = sign * ran.nextInt(NUMBER);
}
return arr;
}

public void testmain() {
long tmplong=System.currentTimeMillis();
//System.out.println();
int [] tmpary = EvoFileTest.getdata();
int tmplth=tmpary.length;
for(int i=0;i<tmplth;i++){
this.addInt(tmpary[i]);
}
Object [] oj=hmres.keySet().toArray();
tmplth=oj.length;
int tmptol=0;
for(int i=0;i<tmplth;i++){
if (i==0){
tmptol= (Integer)hmres.get(oj[i]);
}
// System.out.println(oj[i]+"---"+tmptol);//如需显示结果请看去掉此行注释
}
System.out.println(System.currentTimeMillis()-tmplong);
}

public void addInt(int tmpi){
int tt=1;
if (hm.containsKey(tmpi)){
tt=(Integer) hm.get(tmpi);
tt=tt+1;
hm.put(tmpi, tt);
}else{
hm.put(tmpi, 1);
}
if (tt==t_sum){
hmres.put(tmpi, tt);
}else if (tt>t_sum){
t_sum=tt;
hmres.clear();
hmres.put(tmpi, tt);
}

}
wangzq_ll 2009-03-18
  • 打赏
  • 举报
回复
研究一下
successgl 2009-03-17
  • 打赏
  • 举报
回复
学习
lovezx1028 2009-03-17
  • 打赏
  • 举报
回复
太高深啦。
zhuhaitao321 2009-03-13
  • 打赏
  • 举报
回复
不是很明白,想想再回答
kolige 2009-03-13
  • 打赏
  • 举报
回复
mark
Benjamin0705 2009-03-11
  • 打赏
  • 举报
回复
mark

http://topic.csdn.net/u/20090309/14/64e0e298-9cfd-4e49-8e6e-71125839a4f3.html
gaojava 2009-03-11
  • 打赏
  • 举报
回复
学习下大牛
jadic 2009-03-10
  • 打赏
  • 举报
回复
mark下,周末再看
cleverbing 2009-03-10
  • 打赏
  • 举报
回复
凑个热闹
Coolfatman 2009-03-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 java2000_net 的帖子:]
计数法对于那些数据量不是很大,但数据差异非常大的,并不适合,比如

{Integer.MIN_VALUE,1,Integer.MAX_VALUE}
类似这样的,呵呵,所以还是寻找一个更通用的解决方案。

特别是,如果数据是Long.MAX_VALUE怎么办!

[/Quote]

这个说法是不对的,针对不同密度的数据,当然要不同的处理方式,对于这种数据较分散的情况,增加一个数组存储有数据的下标即可。既然你给出了生成数据的算法,当然要按你数据的构成来分析设计。
lover_cxy2005 2009-03-06
  • 打赏
  • 举报
回复
加号
基督山大树 2009-03-05
  • 打赏
  • 举报
回复
少了枚举,理论上应该快一点!
基督山大树 2009-03-05
  • 打赏
  • 举报
回复
我也弄了一个白痴型的算法,严格来讲不应该讲算法,只是一点点程序,现丑了:
int [] intArry={1,3,5,7,8,3,5,5,3,7,1};
Arrays.sort(intArry);
String strList=Arrays.toString(intArry);
int maxlen=0;
int strlen=0;
String maxStr="";
String indexStr=strList.substring(1,strList.indexOf(", ")+2);
System.out.println(strList+":"+indexStr);
while(indexStr.length()>0){
strlen=indexStr.length();
String temp=strList.replaceAll(indexStr, "");
System.out.println(temp);
int templen=(strList.length()-temp.length())/strlen;
if(templen>maxlen){
maxStr=indexStr;
maxlen=templen;
}else if((templen==maxlen)){
maxStr=maxStr+indexStr;
}
strList=temp;
indexStr=strList.substring(1,strList.indexOf(", ")+2);
}

System.out.println("出现最多的数是::"+maxStr+" 出现次数::"+maxlen);
woainilxt 2009-03-05
  • 打赏
  • 举报
回复
zw
cniao83 2009-03-03
  • 打赏
  • 举报
回复
学习 帮顶
fenghaolun 2009-03-03
  • 打赏
  • 举报
回复
学习
加载更多回复(149)

23,407

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧