サイコロポイントとポーカーストレートのJSアルゴリズム

8月のアップデートチャレンジに参加して13日目です。イベントの詳細については、8月のアップデートチャレンジをご覧ください。

n個のサイコロのポイント

剣はオファー60を指します。n個のサイコロの数

難易度:中程度

件名:leetcode-cn.com/problems/ng…

n個のサイコロを地面に投げると、上向きのすべてのサイコロのポイントの合計はsになります。nを入力し、sのすべての可能な値の発生確率を出力します。

答えをfloatの配列として返す必要があります。ここで、i番目の要素は、転がすことができるn個のサイコロのセットのi番目に小さい確率を表します。

例1:

 输入: 1
 输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
复制代码

例2:

 输入: 2
 输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]
复制代码

制限:1 <= n <= 11

答え

nダイスでは、力ずくの方法を使用すると、時間計算量はO()に達しますが、これは明らかに非現実的です。

動的計画法

後ろの確率またはポイントの合計は、前のサイコロの確率とポイントの合計に関連しているため、動的計画法を使用してこの問題を解決できます。

次のように実行します。

  • 各ラウンドのサイコロの合計の確率としてdpを設定します。1〜6の合計の初期確率はです。

  • サイコロの目数に応じてループする

    • tmpを、このラウンドでサイコロが振られる確率の合計に設定します。初期値はすべて0です。サイコロを5個、すべて1を5個振ると、5の最小の合計を得ることができます。同様に、6n-n + 1 = 5n+1の最小の合計を得るのは難しくありません。
    • 最後のdpの結果によると、新しく追加されたサイコロの数は1から6までしかないため、各ラウンドでダイスロールのtmp [i]を交互に進めます。したがって、tmpが進むたびに、「最後の結果」を追加します。時間/6"。
    • tmpを計算したら、次回使用できるようにtmpをdpに割り当てます。
  • トラバーサルが終了し、dpが返されます。

 /**
  * @param {number} n
  * @return {number[]}
  */
 var dicesProbability = function (n) {
   let dp = new Array(6).fill(1/6);
   for (let i = 2; i <= n; i++) {
     let tmp = new Array(5 * i + 1).fill(0);
     for (let j = 0; j < dp.length; j++) {
       for (let k = 0; k < 6; k++) {
         tmp[j + k] += dp[j] / 6;
       }
     }
     dp = tmp;
   }
   return dp;
 };
复制代码
  • 時間計算量:O(N ^ 2)
  • スペースの複雑さ:O(N)

ポーカーストレート

提供する剣61.ポーカーでストレート

難易度:簡単

件名:leetcode-cn.com/problems/bu…

トランプからランダムに5枚のカードを引き、それがストレートかどうか、つまり5枚のカードが連続しているかどうかを判断します。2から10はそれ自体が数字であり、Aは1、Jは11、Qは12、Kは13であり、大小は0であり、任意の数と見なすことができます。Aは14とは見なされません。

例1:

 输入: [1,2,3,4,5]
 输出: True
复制代码

例2:

 输入: [0,0,1,2,5]
 输出: True
复制代码

制約事項:配列の長さは5で、配列の値は[0,13]です。

答え

例2を見て最初は戸惑いましたが、なぜ[0,0,1,2,5]ストレートなのか、実は0はワイルドカードで、0はどのカードでも使えるので、と見なすことができます[1,2,3,4,5]

5枚ストレートの判定条件は以下のとおりです。

  • 大小の王を除いて、他のすべてのカードは繰り返されません
  • 5枚のカードのうち、「最大のカード-最小のカード(大小の王を除く)<5」を満たす必要があります

方法1セット+トラバーサル

  • Setを使用して重複排除します
  • トラバースするときは、最大カード最大値と最小カード最小値を取得します。
 /**
  * @param {number[]} nums
  * @return {boolean}
  */
 var isStraight = function (nums) {
   const set = new Set();
   let max = 0,
     min = 14;
   for (let num of nums) {
     if (num === 0) continue;
     max = Math.max(max, num);
     min = Math.min(min, num);
     if (set.has(num)) return false;
     set.add(num);
   }
   return max - min < 5;
 };
复制代码
  • 時間計算量:O(N)、この質問ではNは5です
  • スペースの複雑さ:O(N)

方法2の並べ替え+トラバーサル

  • 最初に配列を並べ替えます
  • nums[i]がnums[i+ 1]と等しいかどうかを判断します(繰り返し判断)。等しい場合は、falseを直接返します。
  • 並べ替え後、最後の要素nums [4]が最も高いカード、要素nums [joker]が最も小さいカード、ジョーカーが大小のキングの数です。
 var isStraight = function (nums) {
   let joker = 0; // 用于判断大小王的数量,从而作为下标
   nums.sort((a, b) => a - b); // 记得加上sort()内的函数
   // for循环只需要判断前4位即可
   for (let i = 0; i < 4; i++) {
     if (nums[i] === 0) joker++;
     else if (nums[i] === nums[i + 1]) return false;
   }
   return nums[4] - nums[joker] < 5;
 };
复制代码
  • 時間計算量:O(NlogN)、ソートはクイックソートを使用し、O(NlogN)を必要とします
  • スペースの複雑さ:O(1)

毎日練習してください!フロントエンドのXiaomengは新しいものです、すごい注文できるといいのですが〜

おすすめ

転載: juejin.im/post/6995931634151194637