Dungeon Game
A knight starts in top-left of a dungeon, must reach bottom-right to save the princess. Each cell adds or subtracts health. Find minimum initial health (at least 1) needed.
Example 1
Input: [[-2,-3,3],[-5,-10,1],[10,30,-5]] → Output: 7
Example 2
Input: [[0]] → Output: 1
Solution Approach
Work backwards from bottom-right. dp[i][j] = minimum health needed when entering cell (i,j). dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]).
- dp[m][n-1] = max(1, 1 - dungeon[m-1][n-1]).
- For i from m-1 to 0, j from n-1 to 0 (excluding bottom-right):
- need = min(right_need, down_need) - dungeon[i][j].
- dp[i][j] = max(1, need).
Java
class Solution {
public int calculateMinimumHP(int[][] dungeon) {
int m = dungeon.length, n = dungeon[0].length;
int[][] dp = new int[m + 1][n + 1];
for (int[] row : dp) java.util.Arrays.fill(row, Integer.MAX_VALUE);
dp[m][n-1] = dp[m-1][n] = 1;
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int need = Math.min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j];
dp[i][j] = Math.max(1, need);
}
}
return dp[0][0];
}
}
- Time Complexity: O(M*N)
- Space Complexity: O(M*N)