Skip to content

Commit 70ca5a1

Browse files
committed
resolve #174
1 parent 3afce0d commit 70ca5a1

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

Diff for: src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,4 @@ mod n0169_majority_element;
160160
mod n0171_excel_sheet_column_number;
161161
mod n0172_factorial_trailing_zeroes;
162162
mod n0173_binary_search_tree_iterator;
163+
mod n0174_dungeon_game;

Diff for: src/n0174_dungeon_game.rs

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* [174] Dungeon Game
3+
*
4+
* <style type="text/css">table.dungeon, .dungeon th, .dungeon td {
5+
* border:3px solid black;
6+
* }
7+
*
8+
* .dungeon th, .dungeon td {
9+
* text-align: center;
10+
* height: 70px;
11+
* width: 70px;
12+
* }
13+
* </style>
14+
* The demons had captured the princess (P) 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 (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.
15+
*
16+
* 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.
17+
*
18+
* Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).
19+
*
20+
* In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.
21+
*
22+
*
23+
*
24+
* Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.
25+
*
26+
* For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.
27+
*
28+
* <table class="dungeon">
29+
* <tbody>
30+
* <tr>
31+
* <td>-2 (K)</td>
32+
* <td>-3</td>
33+
* <td>3</td>
34+
* </tr>
35+
* <tr>
36+
* <td>-5</td>
37+
* <td>-10</td>
38+
* <td>1</td>
39+
* </tr>
40+
* <tr>
41+
* <td>10</td>
42+
* <td>30</td>
43+
* <td>-5 (P)</td>
44+
* </tr>
45+
* </tbody>
46+
* </table>
47+
*
48+
*
49+
*
50+
* Note:
51+
*
52+
*
53+
* The knight's health has no upper bound.
54+
* Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.
55+
*
56+
*
57+
*/
58+
pub struct Solution {}
59+
60+
// submission codes start here
61+
62+
/*
63+
DP, 即从每个格子出发到达终点所需的最小生命值为 hp[i][j]
64+
65+
则显然, hp[M-1][N-1] = min(dungeon[M-1][N-1], 0) + 1;
66+
67+
hp[i][j] = min(min(hp[i+1][j], hp[i][j+1]) - dungeon[i][j], 1);
68+
69+
倒推到 hp[0][0] 即可
70+
71+
其实可以优化成 O(M+N) 空间复杂度, 从斜对角线往后推就只需要保存一个小数组, 但是下面这样更简明
72+
*/
73+
impl Solution {
74+
pub fn calculate_minimum_hp(dungeon: Vec<Vec<i32>>) -> i32 {
75+
let (height, width) = (dungeon.len(), dungeon[0].len());
76+
// Using dummy row to simplify logic
77+
let mut hp = vec![vec![i32::max_value(); width+1]; height+1];
78+
hp[height][width-1] = 1;
79+
hp[height-1][width] = 1;
80+
for i in (0..height).rev() {
81+
for j in (0..width).rev() {
82+
hp[i][j] = i32::max(i32::min(hp[i+1][j], hp[i][j+1]) - dungeon[i][j], 1);
83+
}
84+
}
85+
hp[0][0]
86+
}
87+
}
88+
89+
// submission codes end
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::*;
94+
95+
#[test]
96+
fn test_174() {
97+
assert_eq!(
98+
Solution::calculate_minimum_hp(
99+
vec![
100+
vec![-2,-3,3],
101+
vec![-5,-10,1],
102+
vec![10,30,-5],
103+
]),
104+
7);
105+
assert_eq!(
106+
Solution::calculate_minimum_hp(
107+
vec![
108+
vec![1,-4,5,-99],
109+
vec![2,-2,-2,-1]]),
110+
3);
111+
}
112+
}

0 commit comments

Comments
 (0)