|
| 1 | +# 887-super-egg-drop |
| 2 | + |
| 3 | +## Question {#question} |
| 4 | + |
| 5 | +[https://leetcode.com/problems/super-egg-drop/description/](https://leetcode.com/problems/super-egg-drop/description/) |
| 6 | + |
| 7 | +You are given `K` eggs, and you have access to a building with `N` floors from `1` to `N`. |
| 8 | + |
| 9 | +Each egg is identical in function, and if an egg breaks, you cannot drop it again. |
| 10 | + |
| 11 | +You know that there exists a floor `F` with `0 <= F <= N` such that any egg dropped at a floor higher than `F` will break, and any egg dropped at or below floor `F` will not break. |
| 12 | + |
| 13 | +Each _move_, you may take an egg \(if you have an unbroken one\) and drop it from any floor `X` \(with `1 <= X <= N`\). |
| 14 | + |
| 15 | +Your goal is to know **with certainty** what the value of `F` is. |
| 16 | + |
| 17 | +What is the minimum number of moves that you need to know with certainty what `F` is, regardless of the initial value of `F`? |
| 18 | + |
| 19 | +**Example 1:** |
| 20 | + |
| 21 | +```text |
| 22 | +Input: K = 1, N = 2 |
| 23 | +Output: 2 |
| 24 | +Explanation: |
| 25 | +Drop the egg from floor 1. If it breaks, we know with certainty that F = 0. |
| 26 | +Otherwise, drop the egg from floor 2. If it breaks, we know with certainty that F = 1. |
| 27 | +If it didn't break, then we know with certainty F = 2. |
| 28 | +Hence, we needed 2 moves in the worst case to know what F is with certainty. |
| 29 | +``` |
| 30 | + |
| 31 | +**Example 2:** |
| 32 | + |
| 33 | +```text |
| 34 | +Input: K = 2, N = 6 |
| 35 | +Output: 3 |
| 36 | +``` |
| 37 | + |
| 38 | +**Example 3:** |
| 39 | + |
| 40 | +```text |
| 41 | +Input: K = 3, N = 14 |
| 42 | +Output: 4 |
| 43 | +``` |
| 44 | + |
| 45 | +**Note:** |
| 46 | + |
| 47 | +1. `1 <= K <= 100` |
| 48 | +2. `1 <= N <= 10000` |
| 49 | + |
| 50 | +## Thought Process {#thought-process} |
| 51 | + |
| 52 | +1. Brute Force with DP \(TLE\) |
| 53 | + 1. We create an dp array to store the best moves for each eggs and floors combination, where dp\[i\]\[j\] represents the moves for i eggs and j floors |
| 54 | + 2. For current eggs and floors, the best moves is obtained by dropping the egg from 1st floor up to current floor |
| 55 | + 3. The minimum of all these drop tests are our answer |
| 56 | + 4. For each test on ith floor, ranges from 1 to current floor, the egg could either break, so we need to use less egg on remaining floor dp\[curEgg - 1\]\[i - 1\], or it doesn't, so we use dp\[curEgg\]\[curFloor - i\] |
| 57 | + 5. Because we are expecting worst case, the maximum of them + 1 \(current egg drop\) is the answer for dropping at ith floor |
| 58 | + 6. Time complexity O\(KN^2\) |
| 59 | + 7. Space complexity O\(KN\) |
| 60 | +2. DP with Binary |
| 61 | + 1. Notice the function dp\( K - 1, i - 1\) increases when i increase, while on the other hand, dp\(K, N - i\) decreases when i increase |
| 62 | + 2. We can use this observation to speed up the search for minimum i |
| 63 | + 3. Time complexity O\(KNlogN\) |
| 64 | + 4. Space complexity O\(KN\) |
| 65 | +3. DP with Optimality |
| 66 | + 1. Looking at second function, the value increase when N increase, where the i\_opt \(current optimal\) can be use as the starting point for next N |
| 67 | + 2. Time complexity O\(KN\) |
| 68 | + 3. Space complexity O\(KN\) |
| 69 | +4. DP with Problem Rephrase |
| 70 | + 1. Instead of asking how many moves, we rephrase the question into how many floor we can cover for m moves, and K egg |
| 71 | + 2. We create dp array, where dp\[m\]\[k\] stores the floors that we can cover using m moves and k eggs |
| 72 | + 3. For a floor X, when we drop the egg, there are two cases happen here |
| 73 | + 4. If the egg breaks, we need to go down to check dp\[m - 1\]\[k - 1\], we cover dp\[m - 1\]\[k - 1\] + 1 + Y \(top of X\) floors |
| 74 | + 5. Else If the egg doesn't break, we go up and check dp\[m - 1\]\[k\], we cover X + dp\[m -1\]\[k\] floors |
| 75 | + 6. Where we can summarize into dp\[m\]\[k\] = dp\[m - 1\]\[k - 1\] + dp\[m - 1\]\[k\] + 1 |
| 76 | + 7. Time complexity O\(KlogN\) |
| 77 | + 8. Space complexity O\(KN\) |
| 78 | +5. DP above - 1D |
| 79 | + 1. We can reduce the space to O\(k\) |
| 80 | + 2. Since dp\[m\]\[k\] depends on the last row only, we can use dp\[K+1\] to store all the information |
| 81 | + 3. Instead going from forward, we need to travel from backward in order to avoid using the updated value |
| 82 | + 4. Time complexity O\(KlogN\) |
| 83 | + 5. Space complexity O\(K\) |
| 84 | + |
| 85 | +## Solution |
| 86 | + |
| 87 | +```java |
| 88 | +class Solution { |
| 89 | + public int superEggDrop(int K, int N) { |
| 90 | + int[][] memo = new int[K + 1][N + 1]; |
| 91 | + // define memo[i][j] to be the number of moves for i eggs and j floors |
| 92 | + return dp(memo, K, N); |
| 93 | + } |
| 94 | + |
| 95 | + private int dp(int[][] memo, int K, int N) { |
| 96 | + if (N <= 1) return 1; |
| 97 | + if (K == 1) return N; |
| 98 | + if (memo[K][N] > 0) return memo[K][N]; |
| 99 | + // now for current K and N, the problem can break down into dropping eggs |
| 100 | + // from i = [1, N] floors. |
| 101 | + // For each floor, the egg either breaks so we use less egg for remaining floor |
| 102 | + // dp[K - 1][i - 1] or it doesn't that we use dp[K][N - i]. For each case, we |
| 103 | + // are expecting the worst cast, so the max of them + 1 will be compared with |
| 104 | + // current answer; |
| 105 | + int res = Integer.MAX_VALUE; |
| 106 | + for (int i = 1; i <= N; i++) { |
| 107 | + res = Math.min(res, Math.max(dp(memo, K - 1, i - 1), dp(memo, K, N - i)) + 1); |
| 108 | + } |
| 109 | + memo[K][N] = res; |
| 110 | + return res; |
| 111 | + } |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +```java |
| 116 | +class Solution { |
| 117 | + public int superEggDrop(int K, int N) { |
| 118 | + int[][] memo = new int[K + 1][N + 1]; |
| 119 | + // define memo[i][j] to be the number of moves for i eggs and j floors |
| 120 | + return dp(memo, K, N); |
| 121 | + } |
| 122 | + |
| 123 | + private int dp(int[][] memo, int K, int N) { |
| 124 | + if (N <= 1) return 1; |
| 125 | + if (K == 1) return N; |
| 126 | + if (memo[K][N] > 0) return memo[K][N]; |
| 127 | + int res = N; |
| 128 | + int lo = 1, hi = N; |
| 129 | + while (lo < hi) { |
| 130 | + int mi = lo + (hi - lo) / 2; |
| 131 | + int breakMove = dp(memo, K - 1, mi - 1); |
| 132 | + int safeMove = dp(memo, K, N - mi); |
| 133 | + res = Math.min(res, Math.max(breakMove, safeMove) + 1); |
| 134 | + if (breakMove == safeMove) break; |
| 135 | + else if (breakMove > safeMove) hi = mi; |
| 136 | + else lo = mi + 1; |
| 137 | + } |
| 138 | + memo[K][N] = res; |
| 139 | + return res; |
| 140 | + } |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +```java |
| 145 | +class Solution { |
| 146 | + public int superEggDrop(int K, int N) { |
| 147 | + int[][] dp = new int[K + 1][N + 1]; |
| 148 | + for (int j = 1; j <= N; j++) { |
| 149 | + dp[1][j] = j; |
| 150 | + } |
| 151 | + for (int k = 2; k <= K; k++) { |
| 152 | + int x = 1; |
| 153 | + for (int n = 1; n <= N; n++) { |
| 154 | + while (x < n && Math.max(dp[k - 1][x - 1], dp[k][n - x]) > Math.max(dp[k -1][x], dp[k][n - x -1])) x++; |
| 155 | + dp[k][n] = 1 + Math.max(dp[k - 1][x - 1], dp[k][n - x]); |
| 156 | + } |
| 157 | + } |
| 158 | + return dp[K][N]; |
| 159 | + } |
| 160 | +} |
| 161 | +``` |
| 162 | + |
| 163 | +```text |
| 164 | +class Solution { |
| 165 | + public int superEggDrop(int K, int N) { |
| 166 | + int[][] dp = new int[N + 1][K + 1]; |
| 167 | + int m = 0; |
| 168 | + while (dp[m][K] < N) { |
| 169 | + m++; |
| 170 | + for (int k = 1; k <= K; k++) { |
| 171 | + dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1; |
| 172 | + } |
| 173 | + } |
| 174 | + return m; |
| 175 | + } |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +```java |
| 180 | +class Solution { |
| 181 | + public int superEggDrop(int K, int N) { |
| 182 | + int[] dp = new int[K + 1]; |
| 183 | + int m = 0; |
| 184 | + while (dp[K] < N) { |
| 185 | + m++; |
| 186 | + for (int k = K; k > 0; k--) { |
| 187 | + dp[k] += dp[k - 1] + 1; |
| 188 | + } |
| 189 | + } |
| 190 | + return m; |
| 191 | + } |
| 192 | +} |
| 193 | +``` |
| 194 | + |
| 195 | +## Additional {#additional} |
| 196 | + |
0 commit comments