Skip to content

Commit d6e043c

Browse files
committed
update
1 parent bc6f5b9 commit d6e043c

File tree

2 files changed

+112
-2
lines changed

2 files changed

+112
-2
lines changed

Python/dungeon-game.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Time: O(m * n)
2+
# Space: O(m + n)
3+
#
4+
# The demons had captured the princess (P) and imprisoned her
5+
# in the bottom-right corner of a dungeon. T
6+
# he dungeon consists of M x N rooms laid out in a 2D grid.
7+
# Our valiant knight (K) was initially positioned in the top-left room
8+
# and must fight his way through the dungeon to rescue the princess.
9+
#
10+
# The knight has an initial health point represented by a positive integer.
11+
# If at any point his health point drops to 0 or below, he dies immediately.
12+
#
13+
# Some of the rooms are guarded by demons,
14+
# so the knight loses health (negative integers) upon entering these rooms;
15+
# other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).
16+
#
17+
# In order to reach the princess as quickly as possible,
18+
# the knight decides to move only rightward or downward in each step.
19+
#
20+
#
21+
# Write a function to determine the knight's minimum initial health
22+
# so that he is able to rescue the princess.
23+
#
24+
# For example, given the dungeon below, the initial health of
25+
# the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.
26+
#
27+
# Notes:
28+
#
29+
# The knight's health has no upper bound.
30+
# Any room can contain threats or power-ups, even the first room the knight enters
31+
# and the bottom-right room where the princess is imprisoned.
32+
#
33+
34+
class Solution:
35+
# @param dungeon, a list of lists of integers
36+
# @return a integer
37+
def calculateMinimumHP(self, dungeon):
38+
DP = [float("inf") for _ in dungeon[0]]
39+
DP[-1] = 1
40+
41+
for i in reversed(xrange(len(dungeon))):
42+
DP[-1] = max(DP[-1] - dungeon[i][-1], 1)
43+
for j in reversed(xrange(len(dungeon[i]) - 1)):
44+
min_HP_on_exit = min(DP[j], DP[j + 1])
45+
DP[j] = max(min_HP_on_exit - dungeon[i][j], 1)
46+
47+
return DP[0]
48+
49+
# Time: O(m * n logk), where k is the possible maximum sum of loses
50+
# Space: O(m + n)
51+
class Solution2:
52+
# @param dungeon, a list of lists of integers
53+
# @return a integer
54+
def calculateMinimumHP(self, dungeon):
55+
maximum_loses = 0
56+
for rooms in dungeon:
57+
for room in rooms:
58+
if room < 0:
59+
maximum_loses += abs(room)
60+
61+
return self.binarySearch(dungeon, maximum_loses)
62+
63+
def binarySearch(self, dungeon, maximum_loses):
64+
start, end = 1, maximum_loses + 1
65+
result = 0
66+
while start < end:
67+
mid = start + (end - start) / 2
68+
if self.DP(dungeon, mid):
69+
end = mid
70+
else:
71+
start = mid + 1
72+
return start
73+
74+
def DP(self, dungeon, HP):
75+
remain_HP = [0 for _ in dungeon[0]]
76+
remain_HP[0] = HP + dungeon[0][0]
77+
for j in xrange(1, len(remain_HP)):
78+
if remain_HP[j - 1] > 0:
79+
remain_HP[j] = max(remain_HP[j - 1] + dungeon[0][j], 0)
80+
81+
for i in xrange(1, len(dungeon)):
82+
if remain_HP[0] > 0:
83+
remain_HP[0] = max(remain_HP[0] + dungeon[i][0], 0)
84+
else:
85+
remain_HP[0] = 0
86+
87+
for j in xrange(1, len(remain_HP)):
88+
remain = 0
89+
if remain_HP[j - 1] > 0:
90+
remain = max(remain_HP[j - 1] + dungeon[i][j], remain)
91+
if remain_HP[j] > 0:
92+
remain = max(remain_HP[j] + dungeon[i][j], remain)
93+
remain_HP[j] = remain
94+
95+
return remain_HP[-1] > 0
96+
97+
if __name__ == "__main__":
98+
dungeon = [[ -2, -3, 3], \
99+
[ -5, -10, 1], \
100+
[ 10, 30, -5]]
101+
print Solution().calculateMinimumHP(dungeon)
102+
103+
dungeon = [[ -200]]
104+
print Solution().calculateMinimumHP(dungeon)
105+
106+
dungeon = [[0, -3]]
107+
print Solution().calculateMinimumHP(dungeon)

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
LeetCode
22
========
33

4-
Up to date (2014-12-31), there are total `173` problems on [LeetCode Online Judge](https://oj.leetcode.com/).
4+
Up to date (2015-01-06), there are total `174` problems on [LeetCode Online Judge](https://oj.leetcode.com/).
55
The number of problems is increasing recently.
6-
Here is the classification of all `173` problems.
6+
Here is the classification of all `174` problems.
77
I'll keep updating for full summary and better solutions. Stay tuned for updates.
88

99
---
@@ -597,6 +597,7 @@ Problem | Solution | Time | Space | Difficul
597597
[Climbing Stairs]| [climbing-stairs.py] | _O(n)_ | _O(1)_ | Easy |
598598
[Decode Ways] | [decode-ways.py]| _O(n)_ | _O(1)_ | Medium |
599599
[Distinct Subsequences]|[distinct-subsequences.py]| _O(n^2)_ | _O(n)_ | Hard |
600+
[Dungeon Game] | [dungeon-game.py]| _O(m * n)_ | _O(m + n)_ | Hard |
600601
[Edit Distance]|[edit-distance.py]| _O(m * n)_ | _O(m + n)_ | Hard |
601602
[Interleaving String]|[interleaving-string.py]| _O(m * n)_ | _O(m + n)_ | Hard |
602603
[Maximal Rectangle]|[maximal-rectangle.py]| _O(n^2)_ | _O(n)_ | Hard |
@@ -621,6 +622,8 @@ Problem | Solution | Time | Space | Difficul
621622
[decode-ways.py]:https://github.com/kamyu104/LeetCode/blob/master/Python/decode-ways.py
622623
[Distinct Subsequences]:https://oj.leetcode.com/problems/distinct-subsequences/
623624
[distinct-subsequences.py]:https://github.com/kamyu104/LeetCode/blob/master/Python/distinct-subsequences.py
625+
[Dungeon Game]:https://oj.leetcode.com/problems/dungeon-game/
626+
[dungeon-game.py]:https://github.com/kamyu104/LeetCode/blob/master/Python/dungeon-game.py
624627
[Edit Distance]:https://oj.leetcode.com/problems/edit-distance/
625628
[edit-distance.py]:https://github.com/kamyu104/LeetCode/blob/master/Python/edit-distance.py
626629
[Interleaving String]:https://oj.leetcode.com/problems/interleaving-string/

0 commit comments

Comments
 (0)