Skip to content

Commit 14bbaa2

Browse files
author
Chris Wu
committed
no message
1 parent 48e14b0 commit 14bbaa2

7 files changed

+199
-1
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution(object):
2+
def minDistance(self, word1, word2):
3+
N = len(word1)
4+
M = len(word2)
5+
6+
dp = [[float('inf') for _ in xrange(M+1)] for _ in xrange(N+1)]
7+
8+
9+
for i in xrange(1, N+1): dp[i][0] = i #need i deletion for word1[0:i-1] to be ""
10+
for j in xrange(1, M+1): dp[0][j] = j #need i deletion for word1[0:j-1] to be ""
11+
dp[0][0] = 0
12+
13+
for i in xrange(1, N+1):
14+
for j in xrange(1, M+1):
15+
#dp[i][j] := min operation count for dp[0:i] and dp[0:j-1] to be the same.
16+
17+
#if char at i-1 and j-1 are the same, no deletion needed.
18+
if word1[i-1]==word2[j-1]:
19+
dp[i][j] = min(dp[i][j], dp[i-1][j-1])
20+
21+
dp[i][j] = min(dp[i][j], dp[i][j-1]+1) #remove char on word2[j-1]
22+
dp[i][j] = min(dp[i][j], dp[i-1][j]+1) #remove char on word1[i-1]
23+
return dp[N][M]
24+
25+
"""
26+
Time: O(MN)
27+
Space: O(MN)
28+
"""

problems/filling-bookcase-shelves.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
dp[i] := min height when storing books 0~i
3+
for each j try to add a new line at i, see the min height.
4+
5+
Time: O(N^2)
6+
Space: O(N)
7+
"""
8+
class Solution(object):
9+
def minHeightShelves(self, books, shelf_width):
10+
N = len(books)
11+
dp = [float('inf')]*N
12+
13+
for j in xrange(N):
14+
w = 0
15+
h = 0
16+
for i in xrange(j, -1, -1):
17+
w+=books[i][0]
18+
if w>shelf_width: break
19+
20+
h = max(h, books[i][1])
21+
if i==0:
22+
dp[j] = min(dp[j], h)
23+
else:
24+
dp[j] = min(dp[j], dp[i-1]+h)
25+
return dp[-1]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from bisect import bisect_left
2+
3+
class Solution(object):
4+
def lengthOfLIS(self, nums):
5+
dp = [1 for _ in nums]
6+
7+
for i in xrange(1, len(nums)):
8+
for j in xrange(i-1, -1, -1):
9+
if nums[j]<nums[i]:
10+
dp[i] = max(dp[i], dp[j]+1)
11+
12+
return max(dp)
13+
"""
14+
Time: O(N^2)
15+
Spacce: O(N)
16+
"""
17+
18+
19+
class Solution(object):
20+
def lengthOfLIS(self, nums):
21+
dp = []
22+
23+
for n in nums:
24+
i = bisect_left(dp, n)
25+
if i==len(dp):
26+
dp.append(n)
27+
else:
28+
dp[i] = n
29+
30+
return len(dp)
31+
32+
"""
33+
dp[i] := the smallest ending number that has length i+1
34+
"""

problems/longest-string-chain.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import collections
2+
3+
"""
4+
DP
5+
6+
Time: O(NLogN)+O(NSS),
7+
8+
Where N is the number of words and S is the length of each word. (S<=16)
9+
NLogN is for sorting words. NSS is for the double for-loop.
10+
11+
Space: O(NS)
12+
"""
13+
class Solution(object):
14+
def longestStrChain(self, words):
15+
dp = {}
16+
17+
for word in sorted(words, key=len):
18+
dp[word] = 1
19+
for i in xrange(len(word)):
20+
posible_predecessor = word[:i]+word[i+1:]
21+
dp[word] = max(dp.get(word), dp.get(posible_predecessor, 0)+1)
22+
23+
return max(dp.values())
24+
25+
"""
26+
Recursive
27+
28+
Time: O(N^2 x SS),
29+
Basically for every word, check if there are predecessor exist in the words.
30+
If so, keep looking. Until we find the smallest predecessor.
31+
S is the length of each word. isPredecessor takes SS.
32+
33+
Space: O(NS)
34+
"""
35+
class Solution(object):
36+
def longestStrChain(self, words):
37+
def isPredecessor(word, word2):
38+
if not word or not word2: return False
39+
for i in xrange(len(word)):
40+
if word[:i]+word[i+1:]==word2:
41+
return True
42+
return False
43+
44+
def shortestPredecessor(word):
45+
if word in history: return history[word]
46+
shortest_predecessor = word
47+
for word2 in word_group[len(word)-1]:
48+
if isPredecessor(word, word2):
49+
sp = shortestPredecessor(word2)
50+
if len(sp)<len(shortest_predecessor): shortest_predecessor = sp
51+
history[word] = shortest_predecessor
52+
return history[word]
53+
54+
word_group = collections.defaultdict(list)
55+
ans = 1
56+
history = {} # classic memorization for the recursion.
57+
58+
for word in words:
59+
word_group[len(word)].append(word)
60+
61+
for l in xrange(max(word_group.keys()), 0, -1):
62+
if l<ans: break # no need to check since the l is already too small
63+
for word in word_group[l]:
64+
ans = max(ans, l-len(shortestPredecessor(word))+1)
65+
66+
return ans
67+
68+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution(object):
2+
def findNumberOfLIS(self, nums):
3+
L = [1]*len(nums) #LIS
4+
C = [1]*len(nums)
5+
6+
for i in xrange(len(nums)):
7+
for j in xrange(i):
8+
if nums[i]>nums[j]:
9+
if L[j]+1==L[i]:
10+
# If L[j]+1==L[i], it means that the combination of L[j] can simply append nums[i] and reach L[i]
11+
# So add the C[j] to C[i]
12+
C[i] += C[j]
13+
elif L[j]+1>L[i]:
14+
# If L[j]+1==L[i], it means that the combination of L[j] can simply append nums[i] and exceed L[i]
15+
# So update L[i] to L[j]+1 and C[i] to C[j]
16+
L[i] = L[j]+1
17+
C[i] = C[j]
18+
19+
max_length = max(L)
20+
max_length_count = 0
21+
for i, count in enumerate(C):
22+
if L[i]==max_length:
23+
max_length_count+=count
24+
return max_length_count
25+
26+
"""
27+
Time: O(N^2)
28+
Spance: O(1)
29+
"""

problems/palindrome-partitioning.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ def search(s, pal_list):
1111
search(s[i:], pal_list+[s[:i]])
1212
opt = []
1313
search(S, [])
14-
return opt
14+
return opt
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
# Implement from https://www.youtube.com/watch?v=GgP75HAvrlY
3+
class Solution(object):
4+
def numTrees(self, n):
5+
dp = [1, 1, 2]
6+
7+
if n<=2: return dp[n]
8+
9+
for i in xrange(3, n+1):
10+
dp.append(0)
11+
for root in xrange(1, i+1):
12+
dp[i] += dp[root-1]*dp[i-root]
13+
14+
return dp[n]

0 commit comments

Comments
 (0)