Dungeon Game - Complete Solution Guide
Dungeon Game is LeetCode problem 174, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
The demons had captured the princess and imprisoned her in the bottom-right corner of a dungeon . The dungeon consists of m x n rooms laid out in a 2D grid. Our valiant knight was initially positioned in the top-left room and must fight his way through dungeon to rescue the princess. The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately. Some of the rooms are guarded by demons (represented by negative i
Detailed Explanation
The problem presents a dungeon represented by a 2D grid, where each cell can contain either demons (negative integers), magic orbs (positive integers), or be empty (0). A knight starts at the top-left corner and needs to reach the princess in the bottom-right corner. The knight can only move right or down. The knight has initial health, and his health decreases when entering a room with demons and increases when entering a room with magic orbs. The goal is to find the minimum initial health the knight needs to start with to rescue the princess without his health dropping to 0 or below at any point.
Solution Approach
The solution employs dynamic programming to determine the minimum health required at each cell. It starts from the destination (bottom-right) and iterates backward to the starting cell (top-left). For each cell, it calculates the minimum health needed to enter that cell, considering the minimum health needed in the next possible cells (right and down). The minimum of the right and down cells determine the minimum health to arrive at either of those positions. The current dungeon value is subtracted from this health, giving the health needed to *enter* the current cell. If this required health is non-positive, it means the knight can survive the current cell with health 1 (since health cannot be zero or negative). The final value at dp[0][0] represents the minimum initial health required.
Step-by-Step Algorithm
- Step 1: Determine the dimensions of the dungeon (m x n).
- Step 2: Create a DP table `dp` of size (m+1) x (n+1) and initialize all its elements to infinity. The extra row and column are for boundary conditions.
- Step 3: Initialize `dp[m][n-1]` and `dp[m-1][n]` to 1. These represent the minimum health needed to enter the last row/column cells next to the princess.
- Step 4: Iterate through the dungeon from the bottom-right (excluding the princess's cell) to the top-left. Use nested loops that decrement `i` from `m-1` to 0 and `j` from `n-1` to 0.
- Step 5: For each cell (i, j), calculate `min_health_needed_after` as the minimum of `dp[i+1][j]` (health needed moving down) and `dp[i][j+1]` (health needed moving right).
- Step 6: Calculate `health_needed_to_enter` as `min_health_needed_after - dungeon[i][j]`. This is the minimum health needed to survive the current cell.
- Step 7: If `health_needed_to_enter` is less than or equal to 0, set `dp[i][j]` to 1 (meaning at least 1 health is needed). Otherwise, set `dp[i][j]` to `health_needed_to_enter`.
- Step 8: After the loops complete, `dp[0][0]` contains the minimum initial health the knight needs to start with.
Key Insights
- Insight 1: The problem can be efficiently solved using dynamic programming, working backwards from the destination to the starting point.
- Insight 2: Instead of calculating the maximum health the knight can have, we calculate the minimum health he needs at each cell to survive until the end.
- Insight 3: Initialize the DP table with 'infinity' to handle boundary conditions and to ensure the minimum health needed is propagated correctly.
Complexity Analysis
Time Complexity: O(m*n)
Space Complexity: O(m*n)
Topics
This problem involves: Array, Dynamic Programming, Matrix.
Companies
Asked at: Flipkart.