Skip to content

Commit 4d6eba7

Browse files
authored
Merge pull request #965 from yolophg/main
[Helena] Week 8
2 parents 502e019 + ae135d1 commit 4d6eba7

File tree

5 files changed

+121
-0
lines changed

5 files changed

+121
-0
lines changed

clone-graph/yolophg.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Time Complexity: O(N + E) - visit each node once and for each node, we iterate through its neighbors O(E).
2+
# Space Complexity: O(N) - store a copy of each node in the hashmap O(N).
3+
4+
class Solution:
5+
def cloneGraph(self, node):
6+
if node is None:
7+
return None
8+
9+
# dictionary to keep track of cloned nodes (original -> clone)
10+
mp = {}
11+
12+
def clone(node):
13+
if node in mp:
14+
# if the node has already been cloned, return the copy
15+
return mp[node]
16+
17+
# create a new node with the same value
18+
cpy = Node(node.val)
19+
# store it in the map so don't clone it again
20+
mp[node] = cpy
21+
22+
# clone all neighbors and add them to the new node's neighbors list
23+
for n in node.neighbors:
24+
cpy.neighbors.append(clone(n))
25+
26+
return cpy
27+
28+
return clone(node)

longest-common-subsequence/yolophg.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Time Complexity: O(m * n) - each (i, j) pair is computed once and stored, reducing redundant calls.
2+
# Space Complexity: O(m * n) - memoization dictionary stores O(m * n) states.
3+
# - Recursion stack depth is O(m + n) in the worst case.
4+
5+
class Solution:
6+
def longestCommonSubsequence(self, t1: str, t2: str) -> int:
7+
# to memoize results so we don't recompute the same subproblems
8+
m = dict()
9+
10+
# recursive function to compute LCS
11+
def s(i, j):
12+
# base case: if we reach the end of either string, there's nothing left to compare
13+
if i == len(t1) or j == len(t2):
14+
return 0
15+
16+
# if already computed this state, just return the cached value
17+
if (i, j) in m:
18+
return m[(i, j)]
19+
20+
# if the characters match, we take this character and move diagonally
21+
if t1[i] == t2[j]:
22+
m[i, j] = 1 + s(i + 1, j + 1)
23+
else:
24+
# if they don't match, we either move forward in t1 or t2 and take the max
25+
m[i, j] = max(s(i + 1, j), s(i, j + 1))
26+
27+
return m[i, j]
28+
29+
return s(0, 0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Time Complexity: O(n) - loop through the string once, and operations like `max(count.values())` are constant time because there are at most 26 characters.
2+
# Space Complexity: O(1) - `count` only stores counts for up to 26 characters.
3+
4+
class Solution:
5+
def characterReplacement(self, s: str, k: int) -> int:
6+
# keep track of counts in the current window
7+
count = {}
8+
9+
left, right = 0, 0
10+
res = 0
11+
12+
# move the right pointer across the string
13+
for right in range(len(s)):
14+
# update the count for the character at the right pointer
15+
count[s[right]] = count.get(s[right], 0) + 1
16+
17+
# if the window size minus the most frequent char count is bigger than k,
18+
# need to shrink the window from the left
19+
while (right - left + 1) - max(count.values()) > k:
20+
# reduce the count of the char at the left pointer and move the left pointer
21+
count[s[left]] -= 1
22+
left += 1
23+
24+
# update the max length of the valid window
25+
res = max(res, right - left + 1)
26+
27+
return res

number-of-1-bits/yolophg.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Time Complexity: O(k) - check each bit of n once. In the worst case, this is about 32 iterations.
2+
# Space Complexity: O(1) - only use a constant amount of extra space.
3+
4+
class Solution:
5+
def hammingWeight(self, n: int) -> int:
6+
count = 0
7+
8+
# keep going till n becomes 0 (no more bits left to check)
9+
while n:
10+
# check if the last bit is 1 (n % 2 tells us this) and add it to the count
11+
count += (n % 2)
12+
# shift n to the right by 1 to move to the next bit
13+
n = n >> 1
14+
15+
return count

sum-of-two-integers/yolophg.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Time Complexity: O(1) - fixed 32-bit operations, at most 32 iterations
2+
# Space Complexity: O(1) - only uses a few integer variables
3+
4+
class Solution:
5+
def getSum(self, a: int, b: int) -> int:
6+
# 32-bit mask to keep numbers within range
7+
mask = 0xFFFFFFFF
8+
# max value for a signed 32-bit integer (2^31 - 1)
9+
MAX = 0x7FFFFFFF
10+
11+
# keep going until there's no carry left
12+
while b != 0:
13+
# carry is AND operation, then shift left
14+
carry = (a & b) << 1
15+
# XOR does the addition, keep it within 32 bits
16+
a = (a ^ b) & mask
17+
# carry becomes the new b (loop continues if carry exists)
18+
b = carry & mask
19+
20+
# if a is greater than MAX, it's actually a negative number in 32-bit terms
21+
# convert it to proper negative representation
22+
return a if a <= MAX else ~(a ^ mask)

0 commit comments

Comments
 (0)