0まえがき
卵が落ちる問題は、古典的なアルゴリズムの問題と見なすことができ、リートコードにも含まれています。これは、私が収集した数少ない問題の1つです。確かに興味深い問題です。LiYongle先生もビデオで話をしました。この問題。
たまたま、今日は体調が悪く、風邪をひいて、新しいことを学ぶ気力がなかったので、古いものを拾って少し見直しました。
1.はじめに
まず、古典的なアルゴリズムの問題の説明を見てみましょう。
- 手にK個の卵があり、F階がクリティカルなN階建ての建物があります。F階以下から落ちても壊れませんが、逆に卵になります。 F階より高い上層階から落下すると卵が割れるので、臨界層Fを確実に見つけるには少なくとも数回の実験が必要です。
対応するリートコードのタイトルは次のように説明されています。
2.アルゴリズムのアイデア
実際、このトピックで最初に得た反応は、最適なソリューションを直接与えることができるかどうかでした。結果はより良いものでした。その後、いくつかのソリューションを読んだ後、これは動的計画法の古典的な問題であることがわかりました。少なくともアルゴリズムは解くことができます。
明らかに、卵が1つしかない場合は、いくつかのフロアがあり、重要なレイヤーFを見つけるために、いくつかの実験を行う必要があります。フロアが1つしかない場合は、手元にある卵の数に関係なく、必要な実験の数は1回です。
次に、次のように漸化式をすばやく与えることができます。
dp[k][n] = min(1+max(dp[k-1][i-1], dp[k][n-i]) for i in range(1, n+1))
つまり、i階から落下する各操作の状況を調査するために、壊れていない場合は2階の9階のみを検査する必要があり、逆に壊れている場合はkのみを検査する必要があります。 -1個の卵この場合、クリティカルフロアを確実に取得するには、i-1フロアにいくつの実験が必要です。
3.コードの実装
Pythonコードの実装は次のとおりです。
class Solution:
def superEggDrop(self, K: int, N: int) -> int:
dp = [[0 for i in range(N+1)] for _ in range(K+1)]
for k in range(1, K+1):
for n in range(1, N+1):
if k == 1:
dp[k][n] = n
elif n == 1:
dp[k][n] = 1
else:
dp[k][n] = min(1+max(dp[k-1][i-1], dp[k][n-i]) for i in range(1, n+1))
return dp[K][N]
コードを送信した後、いくつかの例をテストしたところ、すべて正しかったのですが、LeetCodeでのコード評価中にタイムアウトエラーが発生しました。結局、上記のコードの時間計算量はO(N 3)O(N ^ 3)です。O (N3)桁違い。
4.アルゴリズムの最適化
もう1つのより洗練されたコード実装は、leetcodeで提供されます。
まず第一に、彼の考えは、先に述べたように、明確なKとNの状況ごとに具体的な答えを明示的に計算することではなく、K個の卵がある場合に最大でn回の実験を行うという問題を解決することです。しきい値フロアを下回っているフロアの数を決定します。
次のように漸化式を与えることもできます。
dp[k][n] = dp[k-1][n-1] + 1 + dp[k][n-1]
その中で、kは前の定義と一致しています。つまりk個の卵があり、nは最大でn個の操作があるdp[k][n]
ことを意味します。つまり、k個の卵がある場合、しきい値フロアより下のフロア数を保証できます。 n回の操作。
5.コードの実装
Pythonコードは次のとおりです。
class Solution:
def superEggDrop(self, K: int, N: int) -> int:
dp = [[0 for _ in range(N+1)] for _ in range(K+1)]
for n in range(1, N+1):
for k in range(1, K+1):
if k == 1:
dp[k][n] = n
else:
dp[k][n] = dp[k-1][n-1] + 1 + dp[k][n-1]
if dp[k][n] >= N:
return n
return -1
前のO(N 3)O(N ^ 3)からのコードの複雑度O (N3)O(N 2)に縮退O(N ^ 2)O (N2)、コードを送信した後、leetcodeでスムーズに渡されます。
6.まとめ
要約すると、基本的にこの質問について説明しました。ただし、現在の実行効率はまだ最適ではありません。LeetCodeには、時間がかかり、さらに最適化できる改善されたソリューションがいくつかありますが、考え方は同じであり、アルゴリズム全体の複雑さもO(N 2)O(N ^ 2)O (N2)ですが、実装の詳細は同じではありません。よりわかりやすく説明するために、上記の記述方法を使用します。これはより説明的です。
読者がより効率的なコードに興味がある場合は、LeetCodeにアクセスして確認できます。