Skip to content
Open

fl #1643

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
30 changes: 30 additions & 0 deletions bt-level-order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
# bfs - use queue fifo, popleft()
# when queue is empty, we know level is complete
levels=[]
if not root:
return levels

# levels = [[3],[]]
# q = [9,20]
level=0
queue = deque([root])
while queue:
levels.append([])
for i in range(len(queue)):
node = queue.popleft()
levels[level].append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
level+=1

return levels
90 changes: 90 additions & 0 deletions course-sched.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Keep track of indegrees using topological sort

# BFS
# O(V+E) time, O(V+E) space
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
indegrees = [0] * numCourses
graph = {}

for pr in prerequisites:
# build the topological sort
indegrees[pr[0]] += 1
# build the adjacency list
if pr[1] not in graph:
graph[pr[1]] = []
graph[pr[1]].append(pr[0])

count = 0
q = deque()

for i in range(numCourses):
# finds the roots - which have 0 prerequisites. Side note - in this problem 1 graph can have many roots
if indegrees[i] == 0:
q.append(i)
count += 1

# every single course has at least 1 prerequisite (deadlock cycle)
if not q:
return False
# all courses have 0 prereqs. Every course is already ready to take - no need for bfs
if count == numCourses:
return True

while q:
curr = q.popleft()
dependencies = graph.get(curr)
if dependencies:
for dep in dependencies:
indegrees[dep] -= 1
if indegrees[dep] == 0:
q.append(dep)
count += 1
# to finish all courses, count must eventually equal numCourses.
# as soon as you decrement indegree to 0 for a course, you add it to the queue and increment count
# if count == numCourses, you already found a valid path for all courses
if count == numCourses:
return True

return False


# DFS O(V+E) time, O(V+E) space
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
self.map = {}
self.path = [False] * numCourses
self.visited = [False] * numCourses

for pr in prerequisites:
if pr[1] not in self.map:
self.map[pr[1]] = []
self.map[pr[1]].append(pr[0])

for i in range(numCourses):
if self.hasCycle(i):
return False

return True

def hasCycle(self, i: int) -> bool:
if self.visited[i]:
return False

if self.path[i]:
return True

self.path[i] = True

neighbours = self.map.get(i)
if neighbours is not None:
for ne in neighbours:
if self.hasCycle(ne):
return True

# you could have A->B->C and A->C. if you don't set path c back to false after exploring through b, the algorithm would think a-c is a cycle
self.path[i] = False
self.visited[i] = True

return False

45 changes: 45 additions & 0 deletions right-side-view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# O(n) time, O(h) space
# DFS
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
result = []
self.helper(root,0,result)
return result

def helper(self, root, level, result):
if not root:
return

if len(result)==level:
result.append(root.val)

self.helper(root.right,level+1,result)
self.helper(root.left, level+1, result)

# BFS
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
res = []
q = deque([root])

while q:
rightSide = None
for i in range(len(q)):
node = q.popleft()
if node:
rightSide=node
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)

if rightSide:
res.append(rightSide.val)

return res