众数抽奖算法-------O(n)级 JAVA实现

问题描述:

假如有大数量(百万,千万级....)的人员编号是固定长度的, 我们从中遍历一遍,

取固定长度每位的众数组合出一个编号作为中奖者(并不是等概率)

不考虑该编号是空编号, 假如一位有多个众数取数值最小的那一位

假如下边的几个编号,长度是12位的:

我们取每个字符串的第一位求出众数,作为中奖者编号的第一位, 每个第二位求众数............

该例子的众数编码为:123456789011

思路:

求众数怎么求?统计每一个数出现的次数

既然求 固定位的众数, 一个位上数字的范围也就是0-9,无论N多大编号每一位的数字都只是这10个数

我们完全可以做个数组来给每个数出现的次数记数,初始值为0

遍历时第x位的数是y就把数组中第一列的第y行计数器+1

遍历完N个编号再统计数组中每位中出现次数最高的那一个数连起来就是 中奖编号

遍历数组就要做循环, 一层控制读N个编号,一层控制读一个编号每位数,

再利用循环变量来给对应的计数器+1;

程序:

(注释掉的部分可以输出 记数数组, 是个10*N的数组)

package learn;

public class Zhongshu {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] arr;
		arr=new int[10][12];//10代表0-9,12代表编码长度
		
		int[] finalarr=new int[12];//记录最终统计结果
		
		String[] str=new String[8]; //8个编号,  每个长度为 12
		str[0]="123456789011";
		str[1]="761436438941";
		str[2]="025824745013";
		str[3]="124321456451";
		str[4]="323456789010";
		str[5]="945645678431";
		str[6]="323456789011";
		str[7]="145654342381";
		
		for(String s : str)
		{
			for(int i=0;i<12;i++)
			{
				arr[s.charAt(i)-'0'][i]++;
				
			}
		}

		for(int j=0;j<12;j++)		//统计表并计算出结果
		{
			for(int i=0;i<10;i++)
			{
				if(arr[i][j]>arr[finalarr[j]][j])
					finalarr[j]=i;
			}
		}
//		for(int j=0;j<10;j++)		//输出统计表
//		{
//			for(int i=0;i<12;i++)
//			{
//				System.out.print(arr[j][i]);
//			}
//			System.out.println(" ");
//		}
		for (int fi : finalarr)
			System.out.print(fi);		

	}

}

因为编号串只遍历了一次,记数表与N的个数无关,所以时间复杂度是 O(n)级别

猜你喜欢

转载自blog.csdn.net/q5706503/article/details/82904022