水贴王之续,找出数组里出现频率最高的元素

找出数组里出现频率最高的元素

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:google搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献;

博客内容:水贴王问题之续

博客时间:2014-5-12;

编程语言:Java ;

编程坏境:Windows 7 专业版 x64;

编程工具:jdk,eclipse x64;

制图工具:office 2007 powerpoint;

硬件信息:7G-3 笔记本;


真言:

痛苦的活着比死了更好。


题目: 

找出数组里出现频率最高的元素。


思路:

利用哈希表统计元素的数目。

哈希表数据结构如下

举例:


平均时间复杂度O(N)

空间复杂度O(N)

实验:


实验1

int[] data ={1,1,2,2,2};

注释 元素2出现了三次。

实验2

int[] data ={1,1,2,2};

注释 元素1出现了2次(当然2也出现了两次,没有求出所有的是不足之处,我暂且只求了其中一个)

代码:

piar.java

package test;

public class pair {
	public int first;
	public int second;
	pair()
	{
		first = second = -1;
	}
}

test.java

package test;


public class test {
	private static final int size = 100 ;
	public static void main(String[] args) {
		int[] data ={1,1,2,2};
		System.out.println(_Find_most_elem(data).first+" "+_Find_most_elem(data).second);
		
		
	}
	
	static pair _Find_most_elem(int[] data)
	{
		int[][] hash = new int[data.length][2];
		int it_hash = 0;
		pair result = new pair();

		
		for(int i=0;i<data.length;i++)
		{
			// find firstly
			if( hash[ data[i] % data.length ][0] == data[i] )
			{
				hash[ data[i] % data.length ][1] ++ ;
			}
			// find secondly
			else
			{
				it_hash = data[i] % data.length;
				while(hash[ it_hash ][0] != data[i] && hash[it_hash ][1] != 0)
				{
					it_hash = (it_hash+1) % data.length ;
				}	
				if( hash[ it_hash ][1] == 0 )
					hash[ it_hash ][0] = data[i];	
				hash[ it_hash ][1] ++;			
			}

		}
		// find most elem
		it_hash = 0;
		for(int i=1;i<data.length;i++)
		{
			if( hash[i][1] > hash[it_hash][1] )
				it_hash = i ;
		}
		if(hash[it_hash][1] != 0)
		{
			result.first = hash[it_hash][0];
			result.second = hash[it_hash][1];
		}
		return result ;                                                                                                                                          
	}
}


博客之续

解决数组里只允许自然数的情况,现在我要解决的问题是可以处理负数。问题来了

这时候哈希表的下标准则要重新定义了

一开始,我们以0为标准,然后去对应哈希表的下表去填充

现在我们重新选择参考对象,以int的最小值作为参考值,这时候我们重新得到的数据值就会溢出,我们要用long类型去保存数据

然后根据模去对应哈希表下表填充数据

实验

int[] data ={1,1,2,2,-2,-2,-2,-2};

哈希表的长度为数组的长度 length =  8

java 最小值:Integer.MIN_VALUE=-2147483648

建表规则

针对data【0】,(1-(-2147583658)) %  length = 1 ;

这时检测表中没有data【0】;则插入;

那么 hash[1][0] = 1; hash[1][1] ++;

否则直接 数量加一;

对于data里的数据都这样处理以此类推。见表如下,空白处为默认初始值。



代码

pair.java

package test;

public class pair {
	public int first;
	public int second;
	pair()
	{
		first = second = -1;
	}
}

test.java

package test;


import java.lang.Integer;

public class test {
	private static final int size = 100 ;
	public static void main(String[] args) {
		int[] data ={1,1,2,2,-2,-2,-2,-2};

		System.out.println(_Find_most_elem(data).first+" "+_Find_most_elem(data).second);
	}
	
	
	
	// data array including 负数
	static pair _Find_most_elem(int[] data) 
	{
		int[][] hash = new int[data.length][2];
		long it_hash = 0;
		pair result = new pair();
		
		for(int i=0;i<data.length;i++)
		{
			// find firstly
			it_hash = (long)data[i] - (long)(Integer.MIN_VALUE);
			if( hash[  (int) (it_hash % (long)(data.length)) ][0] == data[i] )
			{
				hash[ (int) (it_hash % (long)(data.length)) % data.length ][1] ++ ;
			}
			// find secondly
			else
			{
				it_hash = it_hash % (long)data.length;
				while(hash[ (int)it_hash ][0] != data[i] && hash[(int)it_hash ][1] != 0)
				{
					it_hash = (it_hash+1) % (long)data.length ;
				}	
				if( hash[ (int)it_hash ][1] == 0 )
					hash[ (int)it_hash ][0] = data[i];	
				hash[ (int)it_hash ][1] ++;			
			}
		}
		// find most elem
		it_hash = 0;
		for(int i=1;i<data.length;i++)
		{
			if( hash[i][1] > hash[(int)it_hash][1] )
				it_hash = i ;
		}
		if(hash[(int)it_hash][1] != 0)
		{
			result.first = hash[(int)it_hash][0];
			result.second = hash[(int)it_hash][1];
		}
		return result ;                                                                                                                                          
	}
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值