Skip to content

Commit 133c9bc

Browse files
committed
no message
1 parent eca05c7 commit 133c9bc

11 files changed

+375
-1
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution(object):
2+
def uniqueLetterString(self, s):
3+
index = {}
4+
ans = 0
5+
for c in 'abcdefghijklmnopqrstuvwxyz':
6+
index[c.upper()] = [-1, -1]
7+
8+
# count the substring that s[j] is the unique letter
9+
for k, c in enumerate(s):
10+
i, j = index[c]
11+
ans += (j-i) * (k-j)
12+
index[c] = [j, k]
13+
14+
# count the substring that s[j] is the unique letter, because last iteration did not count the last letter
15+
for c in index:
16+
i, j = index[c]
17+
ans += (j-i) * (len(s)-j)
18+
return ans

problems/decode-ways.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Time: O(N), due to the "memo", the time can reduce from O(2^N) to O(N).
3+
Space: O(N)
4+
"""
5+
class Solution(object):
6+
def numDecodings(self, s):
7+
def helper(s, i):
8+
if (s, i) in memo: return memo[(s, i)]
9+
if i>=len(s): return 1
10+
if s[i]=='0': return 0
11+
12+
count = 0
13+
count += helper(s, i+1)
14+
if len(s)-i>=2 and int(s[i:i+2])<=26: count += helper(s, i+2)
15+
memo[(s, i)] = count
16+
return count
17+
18+
memo = {}
19+
return helper(s, 0)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
Use the sliding window to iterate over the sub-strings. At the same time use a counter to track the count.
3+
The operation needed is the (length of the window) - (count of the max count char in the counter)
4+
Since there are at most 26 char in the counter, `max(counter.values())` can be view as a O(1) operation.
5+
6+
Time: O(N)
7+
Space: O(N)
8+
"""
9+
class Solution(object):
10+
def characterReplacement(self, s, k):
11+
counter = collections.Counter()
12+
ans = 0
13+
14+
l = 0
15+
for r in xrange(len(s)):
16+
counter[s[r]] += 1
17+
18+
while r-l+1-max(counter.values())>k:
19+
counter[s[l]] -= 1
20+
l += 1
21+
22+
ans = max(ans, r-l+1)
23+
return ans

problems/maximum-product-subarray.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
Time: O(N)
3+
Space: O(N)
4+
5+
dp[i][0] := the maximum subarray product that includes nums[i]
6+
dp[i][1] := the minimum subarray product that includes nums[i]
7+
"""
8+
class Solution(object):
9+
def maxProduct(self, nums):
10+
if not nums: return 0
11+
dp = [[float('-inf'), float('inf')] for _ in xrange(len(nums))]
12+
13+
dp[0] = [nums[0], nums[0]]
14+
ans = nums[0]
15+
16+
for i in xrange(1, len(nums)):
17+
if nums[i]==0:
18+
dp[i][0] = 0
19+
dp[i][1] = 0
20+
elif nums[i]>0:
21+
dp[i][0] = dp[i-1][0]*nums[i] if dp[i-1][0]>0 else nums[i]
22+
dp[i][1] = dp[i-1][1]*nums[i] if dp[i-1][1]<=0 else nums[i]
23+
else:
24+
dp[i][0] = dp[i-1][1]*nums[i] if dp[i-1][1]<=0 else nums[i]
25+
dp[i][1] = dp[i-1][0]*nums[i] if dp[i-1][0]>0 else nums[i]
26+
27+
ans = max(ans, dp[i][0])
28+
29+
return ans
30+
31+
"""
32+
The above solution can further reduce the space complexity to O(1).
33+
"""
34+
class Solution(object):
35+
def maxProduct(self, nums):
36+
if not nums: return 0
37+
38+
maxLast = nums[0]
39+
minLast = nums[0]
40+
ans = nums[0]
41+
42+
for i in xrange(1, len(nums)):
43+
if nums[i]==0:
44+
newMax = 0
45+
newMin = 0
46+
elif nums[i]>0:
47+
newMax = maxLast*nums[i] if maxLast>0 else nums[i]
48+
newMin = minLast*nums[i] if minLast<=0 else nums[i]
49+
else:
50+
newMax = minLast*nums[i] if minLast<=0 else nums[i]
51+
newMin = maxLast*nums[i] if maxLast>0 else nums[i]
52+
53+
maxLast = newMax
54+
minLast = newMin
55+
ans = max(ans, maxLast)
56+
57+
return ans

problems/maximum-units-on-a-truck.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution(object):
2+
def maximumUnits(self, boxTypes, truckSize):
3+
sortedBox = []
4+
ans = 0
5+
6+
for count, units in boxTypes:
7+
sortedBox.append((units, count))
8+
9+
sortedBox.sort()
10+
11+
while sortedBox and truckSize>0:
12+
units, count = sortedBox.pop()
13+
d = min(count, truckSize)
14+
truckSize -= d
15+
ans += d*units
16+
17+
return ans
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution(object):
2+
def pacificAtlantic(self, heights):
3+
def bfs(q, ocian):
4+
while q:
5+
i0, j0 = q.popleft()
6+
if (i0, j0) in ocian: continue
7+
ocian.add((i0, j0))
8+
9+
for i, j in [(i0+1, j0), (i0-1, j0), (i0, j0+1), (i0, j0-1)]:
10+
if i>=len(heights) or i<0 or j>=len(heights[0]) or j<0: continue
11+
if heights[i][j]>=heights[i0][j0]: q.append((i, j))
12+
13+
pacific = set()
14+
altalantic = set()
15+
q1 = collections.deque()
16+
q2 = collections.deque()
17+
18+
#add top, left to pacific
19+
for j in xrange(len(heights[0])): q1.append((0, j))
20+
for i in xrange(len(heights)): q1.append((i, 0))
21+
22+
#add right, bottom to atalantic
23+
for j in xrange(len(heights[0])): q2.append((len(heights)-1, j))
24+
for i in xrange(len(heights)): q2.append((i, len(heights[0])-1))
25+
26+
bfs(q1, pacific)
27+
bfs(q2, altalantic)
28+
29+
return pacific.intersection(altalantic)
30+

problems/palindromic-substrings.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
dp[i][j] := if s[i:j+1] is palindrome.
3+
1. all length==1 string is palindrome.
4+
2. all length==2 string is palindrome if two are the same.
5+
3. all length>=3 string is palindrome if the outer most two char is the same and have an palindrome string inside.
6+
7+
Time: O(N^2)
8+
Space: 0(N^2)
9+
"""
10+
class Solution(object):
11+
def countSubstrings(self, s):
12+
N = len(s)
13+
dp = [[False]*N for _ in xrange(N)]
14+
ans = 0
15+
16+
#1
17+
for i in xrange(N):
18+
dp[i][i] = True
19+
ans += 1
20+
21+
#2
22+
for i in xrange(N-1):
23+
if s[i]==s[i+1]:
24+
dp[i][i+1] = True
25+
ans += 1
26+
27+
#3
28+
for l in xrange(3, N+1):
29+
for i in xrange(N):
30+
j = i+l-1
31+
if j>=N: continue
32+
if dp[i+1][j-1] and s[i]==s[j]:
33+
dp[i][j] = True
34+
ans += 1
35+
return ans
36+
37+
"""
38+
Iterate through the string, expand around each character.
39+
Like this solution more since it is more intuitive.
40+
41+
Time: O(N^2)
42+
Space: O(1)
43+
"""
44+
class Solution(object):
45+
def countSubstrings(self, s):
46+
def count(l, r, N):
47+
count = 0
48+
49+
while l>=0 and r<N and s[l]==s[r]:
50+
count += 1
51+
l = l-1
52+
r = r+1
53+
return count
54+
55+
N = len(s)
56+
ans = 0
57+
58+
for i in xrange(N):
59+
ans += count(i, i+1, N) #count even length palindrome
60+
ans += count(i, i, N) #count odd length palindrome
61+
return ans

problems/search-suggestions-system.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,66 @@
1+
"""
2+
Time: O(NLogN) for sorting the products, N is the number of product. O(SLogN) for search, S is the number of char of the searchWord.
3+
Space: O(1)
4+
5+
Sort the products then binary search it.
6+
"""
7+
class Solution(object):
8+
def suggestedProducts(self, products, searchWord):
9+
def search(products, word):
10+
l = 0
11+
r = len(products)-1
12+
n = len(word)
13+
14+
while l<=r:
15+
m = (l+r)/2
16+
if products[l].startswith(word): return getTop3(products, word, l)
17+
if products[r].startswith(word): return getTop3(products, word, r)
18+
if products[m].startswith(word): return getTop3(products, word, m)
19+
20+
if products[m][:n]>word:
21+
r = m-1
22+
else:
23+
l = m+1
24+
25+
return []
26+
27+
def getTop3(products, word, i):
28+
suggestion = []
29+
30+
while i-1>=0 and products[i-1].startswith(word):
31+
i -= 1
32+
33+
for j in xrange(i, min(len(products), i+3)):
34+
if not products[j].startswith(word): break
35+
suggestion.append(products[j])
36+
return suggestion
37+
38+
39+
ans = []
40+
products.sort()
41+
42+
currSearchWord = ''
43+
for c in searchWord:
44+
currSearchWord += c
45+
ans.append(search(products, currSearchWord))
46+
47+
return ans
48+
49+
50+
51+
"""
52+
Time: O(M) + O(S^2) ~= O(M). M is the number of char in products. S is number of char of a searchWord.
53+
O(M) to build trie. O(len(prefix)) (~= O(S/2)) to get to the prefix node, and it will perform S time. O(1) to get top 3.
54+
Space: O(M)
55+
56+
Use Trie to store the relation and search it.
57+
"""
158
class Node(object):
259
def __init__(self, c):
360
self.c = c
461
self.nexts = {}
562

63+
664
class Solution(object):
765
def suggestedProducts(self, products, searchWord):
866
ans = []
@@ -37,4 +95,5 @@ def helper(prefix, node):
3795

3896
top3 = []
3997
helper(prefix, node)
40-
return top3
98+
return top3
99+

problems/set-matrix-zeroes.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
Space: O(1)
3+
Time: O(N^2)
4+
5+
Mark matrix[i][0] as string if all matrix[i][?] needs to be set to 0.
6+
Mark matrix[0][j] as string if all matrix[?][j] needs to be set to 0.
7+
There is an edje case where matrix[0][0] cannot represent for row and col at the same time.
8+
So we need an additional variable, firstRowToZero.
9+
10+
Explanation: https://www.youtube.com/watch?v=T41rL0L3Pnw
11+
"""
12+
class Solution(object):
13+
def setZeroes(self, matrix):
14+
firstRowToZero = False
15+
16+
for i in xrange(len(matrix)):
17+
for j in xrange(len(matrix[0])):
18+
if matrix[i][j]==0:
19+
if i!=0:
20+
matrix[i][0] = str(matrix[i][0])
21+
else:
22+
firstRowToZero = True
23+
matrix[0][j] = str(matrix[0][j])
24+
25+
26+
for i in xrange(1, len(matrix)):
27+
if type(matrix[i][0])!=type(''): continue
28+
for j in xrange(len(matrix[0])): matrix[i][j] = 0
29+
30+
for j in xrange(len(matrix[0])):
31+
if type(matrix[0][j])!=type(''): continue
32+
for i in xrange(len(matrix)): matrix[i][j] = 0
33+
34+
if firstRowToZero:
35+
for j in xrange(len(matrix[0])): matrix[0][j] = 0

problems/unique-paths.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution(object):
2+
def uniquePaths(self, m, n):
3+
def factorial(n):
4+
ans = 1
5+
for i in xrange(1, n+1):
6+
ans *= i
7+
return ans
8+
9+
return factorial((m-1)+(n-1))/(factorial(n-1)*factorial(m-1))

0 commit comments

Comments
 (0)