剑指offer第二版——面试题60(java)

面试题:n个骰子的点数

题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的搜有可能的值出现的概率

思路:

n个骰子的点数和的最小值为n,最大值为6n,且n个骰子的所有点数的排列数为6^n——需要先统计出每个点数出现的次数,然后把每个点数出现的次数除以6^n,即每个点数出现的概率

可用两种方法:递归和循环

递归的思路:

想求出n个骰子的点数和,可以先把n个骰子分为两堆:第一堆只有一个;另一堆有n-1个。单独的那堆有6种可能出现的点数,我们需要计算1~6的每一种点数和剩下的n-1个骰子来计算点数和

把n-1个骰子仍然分为两堆……

这是个递归的思路,递归结束的条件是最后只剩下一个骰子

定义一个6n-n+1的数组,将和为s的点数出现的次数保存到数组的第s-n个元素中

(相当于n个for循环,在最后一层for循环的时候把当前的n个固定值加起来,在probList的对应位置+1)

但是基于递归的实现有很多计算是重复的,因此当number变大时,性能也会很慢

 

循环的思路:

用两个数组来存储骰子点数的每个总数出现的次数

在一轮循环中,第一个数组中的第n个数字表示骰子和为n出现的次数

在下一轮循环中,加上一个新的骰子——此时和为n的骰子出现的次数,等于上一轮循环中骰子点数和为n-1、n-2、、n-3、n-4、n-5、n-6的次数的总和,因此,将另一个数组的第n个数字设为前一个数组对应的第n-1、n-2、、n-3、n-4、n-5、n-6个数字之和

(如在上一轮和为20的次数为x,在新的一轮中,加入了一个新的骰子,新的骰子的取值可能为1~6且都只有1次,因此在计算和为20的次数时,需要计算当新骰子为1时,之前为20-1的次数+新骰子为2时,之前为20-2的次数+……+新骰子为6,之前为20-6的次数,即第n-1、n-2、、n-3、n-4、n-5、n-6个数字之和)

 

代码:

// 递归
public class Q60_1 {
	public static void main(String[] args) {
		int n = 5;
		printSum(n);
	}
	
	public static void printSum(int n) {
		int maxV = 6;
		
		if(n<1) {
			return ;
		}
		
		// 初始化数组
		int maxSum = maxV * n;
		int[] probList = new int[maxSum-n+1];
		
		// 递归计算骰子点数
		Probability(n,probList);
		
		// 计算基数
		int total = (int)Math.pow(maxV, n);
		
		// 打印比例
		for(int i=n;i
// 循环
public class Q60_2 {
	static int maxV = 6;
	
	public static void main(String[] args) {
		int n =3;
		printSum(n);
	}
	
	public static void printSum(int n) {
		if(n<1) {
			return;
		}
		
		int[][] prob = new int[2][maxV*n+1];
		int flag = 0;
		
		// 第一轮的初始化
		for(int i=1;i<=maxV;i++) {
			prob[flag][i] = 1;
		}
		
		// k是加入了几颗骰子
		for(int k=2;k<=n;k++) {
			System.out.printf("%d time\n",k);
			for(int i=1;i<=k;i++) {
				prob[1-flag][i]=0;
			}
			
			// i是当前更新的位置
			for(int i=k;i<=maxV*k;i++) {
				prob[1-flag][i]=0;
				// j是当前位置(和)的减去几 如n-1 n-2 n-3 n-4 n-5 n-6中的1~6
				for(int j=1;j<=i && j<=maxV;j++) {
					if(i-j<=maxV*(k-1)) {  // 确认所加的数是上一轮的
						prob[1-flag][i] += prob[flag][i-j];
					}
				}
			}
			flag = 1-flag;
		}
		
		double sum=0;
		int total = (int)Math.pow(maxV, n);
		for(int i=n;i

 

你可能感兴趣的:(剑指offer第二版)