首页 > 代码库 > 数组中n个数出现次数超过1/(1+n),求这些数

数组中n个数出现次数超过1/(1+n),求这些数

先从《编程之美》2.3节“寻找发帖水王”问题说起。

【问题】数组中某个数出现次数超过1/2,求该数。

【思路】遍历数组,只要当前的数同临时变量candidate相同,则计数加1,不相同则计数减1,一旦计数为0则临时变量candidate更换成当前的数,继续上述规则。由于某个数出现次数大于一半,则最后临时变量一定保存了该数。

/*查找数组中出现一半的数*/
	public static int find(int[] candidates) {
		int candidate=0,time=0;
		for (int i = 0; i < candidates.length; i++) {
			if (time==0) {
				candidate=candidates[i];
				time=1;
			}else {
				if (candidate==candidates[i]) {
					time++;
				}else {
					time--;
				}
			}
		}
		return candidate;
	}

**************************************************************************

【扩展题目】《编程之美》的扩展问题,三个数在数组中出现的次数都超过1/4,求这三个数。

【思路】:假设是A、B、C超过了1/4,剩下的数的集合记为D,则所以的A与D相比是超过了A+D的一半,所有的B与D相比是超过了B+D的一半,所有的C与D相比是超过了C+D的一半。转化为上述问题求解。

/*查找数组中三个出现次数超过1/4的数*/
	public static int[] overQuarter(int[] candidates) {
		int[] result=new int[3];
		int[] times=new int[3];
		for (int i = 0; i < candidates.length; i++) {
			if (times[0]==0) {
				times[0]=1;
				result[0]=candidates[i];
			}else if (times[1]==0) {
				times[1]=1;
				result[1]=candidates[i];
			}else if (times[2]==0) {
				times[2]=1;
				result[2]=candidates[i];
			}else if (candidates[i]==result[0]) {
				times[0]++;
			}else if (candidates[i]==result[1]) {
				times[1]++;
			}else if (candidates[i]==result[2]) {
				times[2]++;
			}else {
				times[0]--;
				times[1]--;
				times[2]--;
			}
		}
		return result;
	}

*****************************************************************

【再次扩展】推而广之,2个数出现的次数超过1/3,4个数出现的次数超过1/5……,n个数出现的次数超过1/(n+1),都可以用上面思路求得。



数组中n个数出现次数超过1/(1+n),求这些数