Skip to content

Commit bcef8a4

Browse files
author
wuduhren
committed
updates
1 parent 82ca4d9 commit bcef8a4

13 files changed

+239
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#dp[i][0] := max profit when last action is buy
2+
#dp[i][1] := max profit when last action is sell
3+
class Solution:
4+
def maxProfit(self, prices: List[int]) -> int:
5+
if not prices or len(prices)<=1: return 0
6+
7+
N = len(prices)
8+
dp = [[0, 0] for _ in range(N)]
9+
dp[0] = [-prices[0], 0]
10+
dp[1][0] = max(-prices[1], -prices[0])
11+
dp[1][1] = max(prices[1]+dp[0][0], dp[0][1])
12+
13+
for i in range(2, N):
14+
dp[i][0] = max(dp[i-2][1]-prices[i], dp[i-1][0])
15+
dp[i][1] = max(prices[i]+dp[i-1][0], dp[i-1][1])
16+
return max(dp[-1][0], dp[-1][1], 0)

problems/python3/burst-balloons.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
dfs(l, r) return the max coins that we can get at range l to r.
3+
4+
```
5+
for i in range(l, r+1):
6+
dp[(l, r)] = max(dp[(l, r)], nums[l-1]*nums[i]*nums[r+1] + dfs(l, i-1) + dfs(i+1, r))
7+
```
8+
Assuming i is the last one we extract, the max coins we can get.
9+
10+
Start from the last becasue, we are not able to track the neighbor if we start from the first we extract.
11+
12+
Time: O(N^3)
13+
Space: O(N^2)
14+
"""
15+
class Solution:
16+
def maxCoins(self, nums: List[int]) -> int:
17+
def dfs(l, r)->int:
18+
if l>r: return 0
19+
if (l, r) in dp: return dp[(l, r)]
20+
21+
dp[(l, r)] = 0
22+
for i in range(l, r+1):
23+
dp[(l, r)] = max(dp[(l, r)], nums[l-1]*nums[i]*nums[r+1] + dfs(l, i-1) + dfs(i+1, r))
24+
return dp[(l, r)]
25+
26+
nums = [1]+nums+[1]
27+
dp = {}
28+
return dfs(1, len(nums)-2)

problems/python3/coin-change-ii.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def change(self, amount: int, coins: List[int]) -> int:
3+
dp = [0]*(amount+1)
4+
dp[0] = 1
5+
6+
coins.sort()
7+
8+
for coin in coins:
9+
for a in range(1, amount+1):
10+
if a-coin<0: continue
11+
dp[a] += dp[a-coin]
12+
return dp[-1]

problems/python3/counting-bits.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution:
2+
def countBits(self, n: int) -> List[int]:
3+
ans = [0]*(n+1)
4+
offset = 1
5+
6+
for i in range(1, n+1):
7+
if offset*2==i: offset = offset*2
8+
ans[i] = 1+ans[i-offset]
9+
return ans
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
def numDistinct(self, s: str, t: str) -> int:
3+
def dfs(i, j):
4+
if (i, j) in visited: return visited[(i, j)]
5+
6+
if j>=len(t): return 1
7+
if i>=len(s): return 0
8+
9+
if s[i]==t[j]:
10+
visited[(i, j)] = dfs(i+1, j+1)+dfs(i+1, j)
11+
else:
12+
visited[(i, j)] = dfs(i+1, j)
13+
return visited[(i, j)]
14+
15+
visited = {}
16+
dfs(0, 0)
17+
return dfs(0, 0)

problems/python3/edit-distance.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
dfs(i, j)
3+
i being the unprocessed index in word1.
4+
j, word2.
5+
6+
MAIN LOGIC:
7+
if word1[i]==word2[j], no operation need, return dfs(i+1, j+1)
8+
if not, need 1 operation, so
9+
replace: dfs(i+1, j+1)
10+
insert: dfs(i, j+1)
11+
delete: dfs(i+1, j)
12+
13+
BASE CASE:
14+
If both string are empty (i==N and j==M), no operation needed.
15+
If one string are empty, then the remain operation is the length of the non-empty one.
16+
"""
17+
class Solution:
18+
def minDistance(self, word1: str, word2: str) -> int:
19+
N = len(word1)
20+
M = len(word2)
21+
def dfs(i, j)->int:
22+
if i==N and j==M: return 0
23+
if i==N: return M-j
24+
if j==M: return N-i
25+
26+
if (i, j) in history:
27+
return history[(i, j)]
28+
29+
if word1[i]==word2[j]:
30+
history[(i, j)] = dfs(i+1, j+1)
31+
else:
32+
history[(i, j)] = 1+min(dfs(i+1, j+1), dfs(i+1, j), dfs(i, j+1))
33+
34+
return history[(i, j)]
35+
36+
history = {}
37+
return dfs(0, 0)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
3+
def dfs(i, j):
4+
if (i, j) in history: return False
5+
if i+j==len(s3): return True
6+
if i<len(s1) and s3[i+j]==s1[i] and dfs(i+1, j): return True
7+
if j<len(s2) and s3[i+j]==s2[j] and dfs(i, j+1): return True
8+
history.add((i, j))
9+
return False
10+
11+
if len(s1)+len(s2)!=len(s3): return False
12+
history = set() #store the failed cases
13+
return dfs(0, 0)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Time: O(MN) since the memo at most has MN index.
3+
Space: O(MN)
4+
"""
5+
class Solution:
6+
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
7+
def dfs(i0, j0):
8+
if (i0, j0) in memo: return memo[(i0, j0)]
9+
ans = 1
10+
11+
for i, j in ((i0+1, j0), (i0-1, j0), (i0, j0+1),(i0, j0-1)):
12+
if i<0 or i>=N or j<0 or j>=M: continue
13+
if matrix[i][j]<=matrix[i0][j0]: continue
14+
ans = max(ans, 1+dfs(i, j))
15+
16+
memo[(i0, j0)] = ans
17+
return ans
18+
19+
N = len(matrix)
20+
M = len(matrix[0])
21+
memo = {}
22+
ans = 0
23+
for i in range(N):
24+
for j in range(M):
25+
ans = max(ans, dfs(i, j))
26+
return ans

problems/python3/number-of-1-bits.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""
2+
n = n&(n-1) will turn the right most 1 to 0.
3+
"""
4+
class Solution:
5+
def hammingWeight(self, n: int) -> int:
6+
ans = 0
7+
while n>0:
8+
n = n&(n-1)
9+
ans += 1
10+
return ans
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution:
2+
def isMatch(self, s: str, p: str) -> bool:
3+
def dfs(i, j):
4+
if (i, j) in cache: return cache[(i, j)]
5+
if i>=M and j>=N: return True
6+
if j>=N: return False
7+
8+
match = i<M and (s[i]==p[j] or p[j]=='.')
9+
10+
if j+1<N and p[j+1]=='*':
11+
cache[(i, j)] = (match and dfs(i+1, j)) or dfs(i, j+2) #(use one or more p[j]) or (use zero p[j])
12+
return cache[(i, j)]
13+
14+
if match:
15+
cache[(i, j)] = dfs(i+1, j+1)
16+
return cache[(i, j)]
17+
18+
cache[(i, j)] = False
19+
return cache[(i, j)]
20+
21+
cache = {}
22+
M = len(s)
23+
N = len(p)
24+
return dfs(0, 0)

problems/python3/reverse-bits.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Solution:
2+
def reverseBits(self, n: int) -> int:
3+
res = 0
4+
for i in range(32):
5+
bit = (n >> i) & 1
6+
res = res | (bit << (31 - i))
7+
return res

problems/python3/single-number.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
^ (XOR)
3+
The same will be 0
4+
0^0 = 0
5+
1^1 = 0
6+
7+
Different will be 1
8+
1^0 = 1
9+
0^1 = 1
10+
"""
11+
class Solution:
12+
def singleNumber(self, nums: List[int]) -> int:
13+
ans = 0
14+
for num in nums: ans ^= num
15+
return ans

problems/python3/target-sum.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
Time: O(NS), S is sum(nums), N is len(nums). This is the max possible number of element in "history". Which will be lesser than 2^N.
3+
Space: O(NS)
4+
"""
5+
class Solution:
6+
def findTargetSumWays(self, nums: List[int], target: int) -> int:
7+
def dfs(i, curr):
8+
#cache
9+
if (i, curr) in history:
10+
return history[(i, curr)]
11+
12+
#ending condition
13+
if i==len(nums):
14+
if curr==target:
15+
history[(i, curr)] = 1
16+
else:
17+
history[(i, curr)] = 0
18+
return history[(i, curr)]
19+
20+
history[(i, curr)] = dfs(i+1, curr+nums[i])+dfs(i+1, curr-nums[i])
21+
return history[(i, curr)]
22+
23+
ans = 0
24+
history = {}
25+
return dfs(0, 0)

0 commit comments

Comments
 (0)