Skip to content

Commit b6a6e7f

Browse files
Chris WuChris Wu
Chris Wu
authored and
Chris Wu
committed
no message
1 parent 0a53786 commit b6a6e7f

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

problems/dungeon-game.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""
2+
First, we define an 2-D matrix `hp`.
3+
`hp[i][j]` is, when entering (i, j), the minimum health required, so that we can reach the princess.
4+
5+
So what is the value of `hp[i][j]`?
6+
At `(i, j)`, we always go to next place where its minimum health required is lowest. (Either `(i+1, j)` or `(i, j+1)`).
7+
And if the value is, for example, `-4` at `(i, j)` the requirement will need to add `4` (`- D[i][j]`).
8+
So the minimum requirement at (i, j) will become:
9+
```
10+
min_required = min(hp[i+1][j], hp[i][j+1]) - D[i][j]
11+
```
12+
Now if `min_required` is smaller or equal to `0`, it means that we don't need any requirement at all, set it to minimum, `1`.
13+
```
14+
hp[i][j] = min_required if min_required>1 else 1
15+
```
16+
17+
Now we only need to work it backward so that we can deduct from the value we are sure.
18+
I add extra row and column to the `hp` and set the bottom and the right of the princess to `1`.
19+
so we don't need to look out for boundaries.
20+
```
21+
hp[N][M-1] = 1
22+
hp[N-1][M] = 1
23+
```
24+
25+
The time complexity is O(NM). Since we only traverse the 2-D matrix twice.
26+
One is for constructing `hp`. The second is calculate the value in `hp`.
27+
The space complexity is O(NM), too.
28+
29+
I learn my anser though [here](https://leetcode.com/problems/dungeon-game/discuss/52826/A-very-clean-and-intuitive-solution-(with-explanation)) which has an awesome explaination, too.
30+
"""
31+
class Solution(object):
32+
def calculateMinimumHP(self, D):
33+
N = len(D)
34+
M = len(D[0])
35+
hp = [[float('inf')]*(M+1) for _ in xrange(N+1)]
36+
hp[N][M-1] = 1
37+
hp[N-1][M] = 1
38+
39+
for i in reversed(xrange(N)):
40+
for j in reversed(xrange(M)):
41+
min_required = min(hp[i+1][j], hp[i][j+1]) - D[i][j]
42+
hp[i][j] = min_required if min_required>1 else 1
43+
return hp[0][0]
44+
45+
46+
#Time Limit Exceed
47+
class Solution(object):
48+
def calculateMinimumHP(self, dungeon):
49+
def canPass(health_init):
50+
stack = []
51+
52+
stack.append((0, 0, health_init))
53+
while stack:
54+
i, j, health = stack.pop()
55+
health_left = health+dungeon[i][j]
56+
if health<0 or health_left<0: continue
57+
if i==N-1 and j==M-1: return True
58+
if i+1<N: stack.append((i+1, j, health_left))
59+
if j+1<M: stack.append((i, j+1, health_left))
60+
61+
return False
62+
63+
64+
N = len(dungeon)
65+
M = len(dungeon[0])
66+
l = 0
67+
h = 0
68+
for row in dungeon:
69+
for v in row:
70+
if v<0:
71+
h += -1*v
72+
while l<h:
73+
ans = (l+h)/2
74+
75+
if canPass(ans):
76+
h = ans
77+
else:
78+
l = ans+1
79+
return l+1
80+
81+
#Time Limit Exceed
82+
class Solution(object):
83+
def calculateMinimumHP(self, dungeon):
84+
stack = []
85+
ans = float('inf')
86+
N = len(dungeon)
87+
M = len(dungeon[0])
88+
89+
stack.append((0, 0, 0, 0))
90+
while stack:
91+
i, j, health_curr, health_need = stack.pop()
92+
health_curr += dungeon[i][j]
93+
if health_curr<0:
94+
health_need = max(health_need, -1*health_curr+1)
95+
if i==N-1 and j==M-1:
96+
ans = min(ans, health_need)
97+
if i+1<N: stack.append((i+1, j, health_curr, health_need))
98+
if j+1<M: stack.append((i, j+1, health_curr, health_need))
99+
return ans
100+
101+
102+
103+
104+
105+
106+
107+
108+
109+
110+
111+

problems/koko-eating-bananas.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
`l` is the minimum possible ans.
3+
`h` is the lowest value that we are sure that koko is able to finish all.
4+
Since koko have to rest for the entire K even if he finish that pile already.
5+
The H cannot be lowwer than `len(piles)`.
6+
So we are sure that koko is able to finish all the piles in `max(piles)` of speed.
7+
8+
Now, we need to make logical guess between `l` and `h` by binary search.
9+
If `m` (`(l+h)/2`) is able to finish all the piles in `H`, we lowwer the `h` to `m`.
10+
If `m` is not able to finish, we raise the `l` to `m+1`.
11+
We keep on adjust `l` and `r` until `l` is equal to `r`.
12+
"""
13+
class Solution(object):
14+
def minEatingSpeed(self, piles, H):
15+
def canEatAll(time):
16+
return sum((p+time-1)/time for p in piles) <= H
17+
# time_required = 0
18+
# for count in piles:
19+
# time_required += math.ceil(count/float(time))
20+
# return time_required<=H
21+
22+
l = 1
23+
h = max(piles)
24+
25+
while l<h:
26+
m = (l+h)/2
27+
if canEatAll(m):
28+
h = m
29+
else:
30+
l = m+1
31+
return l

0 commit comments

Comments
 (0)