剑指 Offer 60. n个骰子的点数

137 阅读1分钟

剑指 Offer 60. n个骰子的点数

每个筛子都可以出现1 2 3 4 5 6 中点数,且相互独立

把每个筛子抛出的点数 求和 有可能是重复的,我们先打印下n个筛子抛出筛子点数和的情况,如下代码

其中两层for循环 对应 两个筛子的情况 依次类推 三个for循环对应三个筛子的情况

var arr = [];
for (var i = 1; i <= 6; i++) {
  for (var j = 1; j <= 6; j++) {
      if (arr[i + j ]) {
        arr[i + j ]++;
      } else {
        arr[i + j ] = 1;
      }
  }
}
console.log(arr);

下面是1 ~ 4个筛子的情况,总结出n个筛子组成的数组长度为5n+1 image.png

代码实现 如下

var dicesProbability = function (n) {
  let m = new Map();
  for (let i = 1; i <= n; i++) {
    if (i === 1) {
      m.set(i, [1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
    } else {
      let pre = m.get(i - 1);
      let cur = new Array(5 * i + 1).fill(0);
      for (let j = 1; j <= 6; j++) {
        for (let p = 0; p < pre.length; p++) {
          cur[p - 1 + j] += (1 / 6) * pre[p];
        }
      }
      m.set(i, cur);
    }
  }
  return m.get(n);
};

一个筛子 --> 两个筛子过程发生什么,新增加了一个筛子抛着玩

  • 如果抛出的点数为1,生成新的数组cur[p]+=(1/6)*pre[p] ,其中p为0 ~ pre.length - 1
  • 如果抛出的点数为2,生成新的数组cur[p+1]+=(1/6)*pre[p]
  • 如果抛出的点数为3,生成新的数组cur[p+2]+=(1/6)*pre[p]
  • 如果抛出的点数为4,生成新的数组cur[p+3]+=(1/6)*pre[p]
  • 如果抛出的点数为5,生成新的数组cur[p+4]+=(1/6)*pre[p]
  • 如果抛出的点数为6,生成新的数组cur[p+5]+=(1/6)*pre[p]

未命名文件 (4).jpg