File tree Expand file tree Collapse file tree 5 files changed +210
-0
lines changed
best-time-to-buy-and-sell-stock
encode-and-decode-strings
implement-trie-prefix-tree Expand file tree Collapse file tree 5 files changed +210
-0
lines changed Original file line number Diff line number Diff line change 1+ '''
2+ # 121. Best Time to Buy and Sell Stock
3+
4+ use **bottom-up dynamic programming** to solve the problem.
5+
6+ ## Time and Space Complexity
7+ ```
8+ TC: O(n)
9+ SC: O(1)
10+ ```
11+
12+ ## TC is O(n):
13+ - iterating through the list just once to find the maximum profit. = O(n)
14+
15+ ## SC is O(1):
16+ - using two variables to store the minimum price and maximum profit. = O(1)
17+ '''
18+ class Solution :
19+ def maxProfit (self , prices : List [int ]) -> int :
20+ if len (prices ) == 1 :
21+ return 0
22+
23+ lowest_price = prices [0 ] # SC: O(1)
24+ max_profit = 0 # SC: O(1)
25+
26+ for price in prices : # TC: O(n)
27+ lowest_price = min (price , lowest_price )
28+ curr_profit = price - lowest_price
29+ max_profit = max (curr_profit , max_profit )
30+
31+ return max_profit
Original file line number Diff line number Diff line change 1+ '''
2+ # 271. Encode and Decode Strings
3+
4+ ## Time and Space Complexity
5+
6+ Use ":" as a separator and also store the length of each string to decode the string correctly.
7+
8+
9+ ### encode
10+
11+ ```
12+ TC: O(n * k)
13+ SC: O(m)
14+ ```
15+
16+ #### TC is O(n * k):
17+
18+ - iterating through the list of strings and appending each string to the result. = O(n * k)
19+ - f-string is O(k)
20+
21+ #### SC is O(m):
22+ - storing the result in a string.
23+
24+ ### decode
25+
26+ ```
27+ TC: O(m)
28+ SC: O(m)
29+ ```
30+
31+ #### TC is O(m):
32+ - iterating over the string until the string length is 0. = O(m)
33+ - do list slicings for extract parts and removing the processed section = each operation takes O(k)
34+
35+ #### SC is O(m):
36+ - storing the result in a list(total length of strings is m) = O(m)
37+
38+ '''
39+
40+ class Solution :
41+ """
42+ @param: strs: a list of strings
43+ @return: encodes a list of strings to a single string.
44+ """
45+ def encode (self , strs ):
46+ result = ''
47+ for str in strs : # TC: O(n)
48+ result += f"{ len (str )} :{ str } " # TC: O(k)
49+ return result
50+
51+ """
52+ @param: str: A string
53+ @return: decodes a single string to a list of strings
54+ """
55+ def decode (self , str ):
56+ result = []
57+
58+ while len (str ) > 0 : # TC: O(m)
59+ length = int (str [:1 ]) # TC: O(k)
60+ string = str [2 :length + 2 ] # TC: O(k)
61+ str = str [length + 2 :] # TC: O(k)
62+
63+ result .append (string ) # SC: O(m)
64+
65+ return result
Original file line number Diff line number Diff line change 1+ '''
2+ # 49. Group Anagrams
3+
4+ use **hash map** to solve the problem.
5+
6+ ## Time and Space Complexity
7+ ```
8+ TC: O(N * K * Log(K))
9+ SC: O(N * K)
10+ ```
11+
12+ ## TC is O(N * K * Log(K)):
13+ - iterating through the list of strings and sorting each string. = O(N * K * Log(K))
14+
15+ ## SC is O(N * K):
16+ - using a hash map to store the sorted strings. = O(N * K)
17+ '''
18+ class Solution :
19+ def groupAnagrams (self , strs : List [str ]) -> List [List [str ]]:
20+ result = defaultdict (list )
21+
22+ for str in strs : # TC: O(N)
23+ sorted_key = '' .join (sorted (str )) # sorting 👉 TC: O(K * Log(K))
24+ result [sorted_key ].append (str ) # TC: O(1) on average
25+
26+ return list (result .values ())
27+
Original file line number Diff line number Diff line change 1+ '''
2+ # 208. Implement Trie (Prefix Tree)
3+
4+ ```
5+ - Node structure
6+ {children: {char: {children: { ... }, is_end: False}}, is_end: False}
7+ ```
8+
9+ ## Time and Space Complexity
10+
11+ ```
12+ TC: O(n)
13+ SC: O(n)
14+ ```
15+
16+ #### TC is O(n):
17+ - insert, search, startsWith: iterating through the word just once. = O(n)
18+
19+ #### SC is O(n):
20+ - insert, search, startsWith: using a hash map to store the children nodes. = O(n)
21+ '''
22+
23+ class Trie :
24+ def __init__ (self ):
25+ self .root = {"children" : {}, "is_end" : False }
26+
27+ def insert (self , word : str ) -> None :
28+ node = self .root
29+ for char in word :
30+ if char not in node ["children" ]:
31+ node ["children" ][char ] = {"children" : {}, "is_end" : False }
32+ node = node ["children" ][char ]
33+ node ["is_end" ] = True
34+
35+ def search (self , word : str ) -> bool :
36+ node = self .root
37+ for char in word :
38+ if char not in node ["children" ]:
39+ return False
40+ node = node ["children" ][char ]
41+ return node ["is_end" ]
42+
43+ def startsWith (self , prefix : str ) -> bool :
44+ node = self .root
45+ for char in prefix :
46+ if char not in node ["children" ]:
47+ return False
48+ node = node ["children" ][char ]
49+ return True
Original file line number Diff line number Diff line change 1+ '''
2+ # 139. Word Break
3+
4+ use dynamic programming to check if the string is segmentable.
5+
6+ > **use dp to avoid redundant computations:**
7+ > backtracking approach will check all possible combinations of words recursively, which has time complexity of O(2^n))
8+
9+ ## Time and Space Complexity
10+
11+ ```
12+ TC: O(n^2)
13+ SC: O(n)
14+ ```
15+
16+ #### TC is O(n^2):
17+ - nested loops for checking if the string is segmentable. = O(n^2)
18+ - outer loop: iterate each char index from the start to the end. = O(n)
19+ - inner loop: for each index in the outer loop, checks substrings within the range of valid words in wordDict. = worst case, O(n)
20+
21+ #### SC is O(n):
22+ - using a dp array to store whether index i is segmentable. = O(n)
23+ '''
24+ class Solution :
25+ def wordBreak (self , s : str , wordDict : List [str ]) -> bool :
26+ word_set = set (wordDict )
27+ n = len (s )
28+
29+ segment_dp = [False ] * (n + 1 ) # SC: O(n)
30+ segment_dp [0 ] = True # Base case: an empty string is segmentable
31+
32+ for end in range (1 , n + 1 ): # TC: O(n^2)
33+ for start in range (end ):
34+ if segment_dp [start ] and s [start :end ] in word_set :
35+ segment_dp [end ] = True
36+ break
37+
38+ return segment_dp [n ]
You can’t perform that action at this time.
0 commit comments