您的位置:首页 > 职场人生

剑指Offer面试题43n个骰子的点数(动态规划),面试题44扑克牌的顺子

2017-07-30 19:56 881 查看

面试题43:n个骰子的点数(动态规划)

扔n个骰子,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率。

思路:n个骰子和最小为你,最大为6n,根据排列组合,n个骰子的所有点数的排列为6^n,我们需要先统计出每一种点数和的出现次数,然后除以6^n即为概率。动态规划分析如下:

当有n个骰子,点数和为s,则每一种点数和出现的次数记为f(n,s)。现在假设我有n-1个骰子,再增加一个骰子,它的点数只能是1到6,则n个骰子得到点数和为s的情况有6种,所以f(n,s)=f(n-1,s-1)+f(n-1,s-2)+…+f(n-1,s-6),当有一个骰子时,f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。

具体到程序,用两个数组,在第一次循环中,第一个数组中的第s个数字表示和为s出现的次数。在下一次循环中,加上一个新骰子,此时和为s出现的次数等于上一次循环中和为s-1,s-2,s-3直到s-6出现次数的总和,所以把另一个数组的第s个数字设为前一个数组对应的第s-1,s-2,s-3直到s-6之和,下一轮循环交换数组重复这一过程。

Java实现如下:

public class Probability {
static void printProbability(int number){
if (number<1)
return;
int g_maxValue = 6;
int[][] pProbabilitys = new int[2][g_maxValue * number + 1];
int flag = 0; // 控制在2个数组间切换
// 一个骰子时
for (int i = 1; i <= g_maxValue; i++)
pProbabilitys[flag][i] = 1;
// 开始加骰子
for (int k = 2; k <= number; k++) {
// 不可能出现的次数标记为0
for (int i = 0; i < k; i++)
pProbabilitys[1-flag][i] = 0;
// 可能出现的次数
for (int i = k; i <= g_maxValue*number; i++) {
pProbabilitys[1-flag][i] = 0;
for (int j = 1; j <= i && j <= g_maxValue; j++)
pProbabilitys[1-flag][i] += pProbabilitys[flag][i-j];
}
flag = 1-flag;
}
double total = Math.pow(g_maxValue, number);
for (int i = 1; i <= g_maxValue*number; i++) {
double ratio = pProbabilitys[flag][i] / total;
System.out.println(i + ": " + ratio);
}
}

public static void main(String[] args) {
printProbability(1);
}
}


面试题44:扑克牌的顺子

从一副牌中随机抽取5张判断是不是顺子,A为1,大小王可为任意值。

思路:把5张牌看成大小为5的数组,大小王视为0,首先把数组排序,再统计数组中0的个数,还要统计有序数组中相邻数字之间的空缺数,去和0的个数相比,0比空缺数多的话就是顺子。

Java实现如下:

import java.util.Arrays;
public class IsContinuous {
static boolean isContinuous(int[] arr) {
if (arr == null || arr.length < 1)
return false;
int length = arr.length;
Arrays.sort(arr);
int numbersOfZero = 0;
int numberOfGap = 0;
for (int i = 0; i < length && arr[i] == 0; i++)
++numbersOfZero;
int notZeroIndex = numbersOfZero;
while (notZeroIndex < length-1) {
// 有重复的数肯定不是顺子
if (arr[notZeroIndex] == arr[notZeroIndex+1])
return false;
numberOfGap += arr[notZeroIndex+1] - arr[notZeroIndex] - 1;
notZeroIndex++;
}
return numberOfGap > numbersOfZero ? false : true;
}
public static void main(String[] args) {
System.out.println(isContinuous(new int[]{2,4,5,0,0}));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息