Skip to content

Commit 71a7e6d

Browse files
authored
Merge pull request #1393 from ayosecu/main
[ayosecu] WEEK 05 Solutions
2 parents c65a77f + 8cff5f9 commit 71a7e6d

File tree

5 files changed

+213
-0
lines changed

5 files changed

+213
-0
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import List
2+
class Solution:
3+
"""
4+
- Time Complexity: O(n), n = len(prices)
5+
- Space Complexity: O(1)
6+
"""
7+
def maxProfit(self, prices: List[int]) -> int:
8+
min_price = float("inf")
9+
max_profit = 0
10+
11+
for price in prices:
12+
min_price = min(min_price, price)
13+
max_profit = max(max_profit, price - min_price)
14+
15+
return max_profit
16+
17+
tc = [
18+
([7,1,5,3,6,4], 5),
19+
([7,6,4,3,1], 0)
20+
]
21+
22+
for i, (prices, e) in enumerate(tc, 1):
23+
sol = Solution()
24+
r = sol.maxProfit(prices)
25+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

encode-and-decode-strings/ayosecu.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class Solution:
2+
"""
3+
@param: strs: a list of strings
4+
@return: encodes a list of strings to a single string.
5+
- Time Complexity: O(N), N = All characters in strs
6+
- Space Complexity: O(N)
7+
"""
8+
def encode(self, strs):
9+
# Encode Format: xx#str
10+
# xx:len(s)
11+
# strs = ["abc", "defg"]
12+
# Encoded String = 3#abc4#defg
13+
enc_list = []
14+
for s in strs:
15+
enc_list.append(f"{len(s)}#{s}")
16+
return "".join(enc_list)
17+
18+
"""
19+
@param: str: A string
20+
@return: decodes a single string to a list of strings
21+
- Time Complexity: O(n), n = len(str)
22+
- Space Complexity: O(1), if output is excluded.
23+
"""
24+
def decode(self, str):
25+
result = []
26+
27+
i = 0
28+
while i < len(str):
29+
j = i
30+
while str[j] != "#":
31+
j += 1
32+
n = int(str[i:j])
33+
i = j + 1
34+
result.append(str[i:i + n])
35+
i += n
36+
37+
return result
38+
39+
tc = [
40+
(["lint","code","love","you"], "4#lint4#code4#love3#you"),
41+
(["we", "say", ":", "yes"], "2#we3#say1#:3#yes")
42+
]
43+
44+
for i, (p1, p2) in enumerate(tc, 1):
45+
sol = Solution()
46+
r = sol.encode(p1)
47+
print(f"TC {i} - encode() is Passed!" if r == p2 else f"TC {i} - encode() is Failed! - Expected:{p2}, Result: {r}")
48+
r = sol.decode(p2)
49+
print(f"TC {i} - decode() is Passed!" if r == p1 else f"TC {i} - decode() is Failed! - Expected:{p1}, Result: {r}")

group-anagrams/ayosecu.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from typing import List
2+
from collections import defaultdict
3+
4+
class Solution:
5+
"""
6+
- Time Complexity: O(nklogk), n = len(strs), k = Max of len(strs[i])
7+
- for loop => O(n)
8+
- sorted(s) => O(klogk)
9+
- Space Complexity: O(nk), dictionary size
10+
"""
11+
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
12+
# dictionary
13+
dic = defaultdict(list)
14+
15+
for s in strs:
16+
ss = "".join(sorted(s))
17+
dic[ss].append(s)
18+
19+
return list(dic.values())
20+
21+
tc = [
22+
(["eat","tea","tan","ate","nat","bat"], [["bat"],["nat","tan"],["ate","eat","tea"]]),
23+
([""], [[""]]),
24+
(["a"], [["a"]])
25+
]
26+
27+
for i, (strs, e) in enumerate(tc, 1):
28+
sol = Solution()
29+
r = sol.groupAnagrams(strs)
30+
r_sorted = sorted([sorted(group) for group in r])
31+
e_sorted = sorted([sorted(group) for group in e])
32+
print(f"TC {i} is Passed!" if r_sorted == e_sorted else f"TC {i} is Failed! - Expected: {e_sorted}, Result: {r_sorted}")

implement-trie-prefix-tree/ayosecu.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.isEnd = False
5+
6+
class Trie:
7+
# Init Structure
8+
def __init__(self):
9+
self.root = TrieNode()
10+
11+
# Time Complexity: O(n), n = len(word)
12+
# Space Complexity: O(n)
13+
def insert(self, word: str) -> None:
14+
current = self.root
15+
for c in word:
16+
if c not in current.children:
17+
current.children[c] = TrieNode()
18+
current = current.children[c]
19+
current.isEnd = True
20+
21+
# Time Complexity: O(n), n = len(word)
22+
# Space Complexity: O(1)
23+
def search(self, word: str) -> bool:
24+
current = self.root
25+
for c in word:
26+
if c not in current.children:
27+
return False
28+
current = current.children[c]
29+
return current.isEnd # Check whole characters were matched
30+
31+
# Time Complexity: O(n), n = len(prefix)
32+
# Space Complexity: O(1)
33+
def startsWith(self, prefix: str) -> bool:
34+
current = self.root
35+
for c in prefix:
36+
if c not in current.children:
37+
return False
38+
current = current.children[c]
39+
return True
40+
41+
42+
tc = [
43+
("insert", "apple", None),
44+
("search", "apple", True),
45+
("search", "app", False),
46+
("startsWith", "app", True),
47+
("insert", "app", None),
48+
("search", "app", True),
49+
("insert", "banana", None),
50+
("search", "banana", True),
51+
("search", "bananas", False),
52+
("startsWith", "ban", True),
53+
("startsWith", "baz", False),
54+
("search", "", False),
55+
("startsWith", "", True)
56+
]
57+
58+
trie = Trie()
59+
for i, (op, value, expected) in enumerate(tc, 1):
60+
if op == "insert":
61+
result = trie.insert(value)
62+
elif op == "search":
63+
result = trie.search(value)
64+
elif op == "startsWith":
65+
result = trie.startsWith(value)
66+
else:
67+
result = None # unknown operation
68+
69+
if result == expected:
70+
print(f"TC {i} is Passed!")
71+
else:
72+
print(f"TC {i} is Failed! - Op: {op}('{value}'), Expected: {expected}, Result: {result}")

word-break/ayosecu.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from typing import List
2+
3+
class Solution:
4+
"""
5+
- Time Complexity: O(n^2), n = len(s)
6+
- Space Complexity: O(n + m)
7+
- n = len(s) = dp size
8+
- m = The number of characters in wordDict (wordDict size)
9+
"""
10+
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
11+
n = len(s)
12+
wordDict = set(wordDict)
13+
14+
# Use DP: dp[i] => s[0:i] is possible to be seperated by dictionary words
15+
dp = [False] * (n + 1)
16+
dp[0] = True
17+
18+
for i in range(1, n + 1):
19+
for j in range(i):
20+
if dp[j] and s[j:i] in wordDict:
21+
dp[i] = True
22+
break # s[i-1] is possible => don't need to check forward string
23+
24+
return dp[-1] # check s[0:n]
25+
26+
tc = [
27+
("leetcode", ["leet","code"], True),
28+
("applepenapple", ["apple","pen"], True),
29+
("catsandog", ["cats","dog","sand","and","cat"], False)
30+
]
31+
32+
sol = Solution()
33+
for i, (s, wordDict, e) in enumerate(tc, 1):
34+
r = sol.wordBreak(s, wordDict)
35+
print(f"TC {i} is Passed!" if r == e else f"TC {i} is Failed! - Expected: {e}, Result: {r}")

0 commit comments

Comments
 (0)