Skip to content

[SAM] Week 9 solutions #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions clone-graph/samthekorean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# TC : O(n)
# SC : O(n)
class Solution:
def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
if not node:
return None

# Dictionary to store cloned nodes
cloned_nodes = {}
# BFS queue starting with the original node
queue = deque([node])

# Clone the original node
cloned_node = Node(node.val)
cloned_nodes[node] = cloned_node

while queue:
current_node = queue.popleft()

# Iterate through neighbors of the current node
for neighbor in current_node.neighbors:
if neighbor not in cloned_nodes:
# Clone the neighbor and add it to the queue
cloned_neighbor = Node(neighbor.val)
cloned_nodes[neighbor] = cloned_neighbor
queue.append(neighbor)

# Add the cloned neighbor to the cloned current node's neighbors list
cloned_nodes[current_node].neighbors.append(cloned_nodes[neighbor])

return cloned_node
34 changes: 34 additions & 0 deletions course-schedule/samthekorean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# V is number of verticles and E is number of edges
# TC : O(V+E)
# SC : O(V+E)
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:

pre = defaultdict(list)

for course, p in prerequisites:
pre[course].append(p)

taken = set()

def dfs(course):
if not pre[course]:
return True

if course in taken:
return False

taken.add(course)

for p in pre[course]:
if not dfs(p):
return False

pre[course] = []
return True

for course in range(numCourses):
if not dfs(course):
return False

return True
49 changes: 49 additions & 0 deletions design-add-and-search-words-data-structure/samthekorean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# n: number of words | m: length of the word
# TC: O(n*m)
# SC: O(n*m)


class TrieNode:
def __init__(self):
self.children = {} # Dictionary to store child TrieNodes
self.is_word = False # Flag to indicate if a word ends at this node


class WordDictionary:
def __init__(self):
# Initialize WordDictionary with a root TrieNode.
self.root = TrieNode()

def addWord(self, word):
# Add a word to the Trie.
current_node = self.root

# Traverse each character in the word
for character in word:
# Create a new TrieNode if the character doesn't exist in children
current_node = current_node.children.setdefault(character, TrieNode())

# Mark the end of the word at the last character's node
current_node.is_word = True

def search(self, word):

def dfs(node, index):
if index == len(word):
# If reached end of the word, check if current node marks the end of a word
return node.is_word

if word[index] == ".":
# Handle wildcard character '.': Try all possible children
for child in node.children.values():
if dfs(child, index + 1):
return True
elif word[index] in node.children:
# Regular character: Move to the next node
return dfs(node.children[word[index]], index + 1)

# If no match found, return False
return False

# Start DFS from the root of the Trie
return dfs(self.root, 0)
26 changes: 26 additions & 0 deletions number-of-islands/samthekorean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# TC : O(n) where n is the number of elements in the two-dimensional list.
# SC : O(n) where n is the depth of the stack of recursive calls.
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def dfs(r, c):
# Mark the current cell as visited by setting it to "0"
grid[r][c] = "0"
# Explore all four possible directions (right, down, left, up)
for dr, dc in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
nr, nc = r + dr, c + dc
# Check if the new position is within bounds and is land ("1")
if (
0 <= nr < len(grid)
and 0 <= nc < len(grid[0])
and grid[nr][nc] == "1"
):
dfs(nr, nc)

island_count = 0
# Traverse each cell in the grid
for r in range(len(grid)):
for c in range(len(grid[0])):
if grid[r][c] == "1": # Found an island
island_count += 1 # Increment the island count
dfs(r, c) # Sink the entire island
return island_count # Return the total number of islands
44 changes: 44 additions & 0 deletions pacific-atlantic-water-flow/samthekorean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# m is number of rows and n is number of columns
# TC : O(m*n)
# SC : O(m*n)
class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
ROWS, COLS = len(heights), len(heights[0])
DIRECTIONS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
pacific, atlantic = set(), set()
result: List[List[int]] = []

def dfs(
r: int, c: int, ocean_set: Set[Tuple[int, int]], prev_height: int
) -> None:
if (
r < 0
or r >= ROWS
or c < 0
or c >= COLS
or (r, c) in ocean_set
or heights[r][c] < prev_height
):
return

ocean_set.add((r, c))

for dr, dc in DIRECTIONS:
dfs(r + dr, c + dc, ocean_set, heights[r][c])

# Water Flow Simulation from Pacific (Top and Left borders)
for col in range(COLS):
dfs(0, col, pacific, heights[0][col])
dfs(ROWS - 1, col, atlantic, heights[ROWS - 1][col])

for row in range(ROWS):
dfs(row, 0, pacific, heights[row][0])
dfs(row, COLS - 1, atlantic, heights[row][COLS - 1])

# Finding cells reachable by both Pacific and Atlantic
for r in range(ROWS):
for c in range(COLS):
if (r, c) in pacific and (r, c) in atlantic:
result.append([r, c])

return result