Skip to content
Open
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
22 changes: 22 additions & 0 deletions Problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Problem1 Find Judge (https://leetcode.com/problems/find-the-town-judge/)
# Time Complexity: O(n + t),We loop through the trust list once (t edges), then loop through all n people once.
# Space Complexity: O(n),We store an indegrees array of size n+1.
# Approach:
# The town judge is trusted by everyone else but trusts nobody.
# For each trust pair [a, b], a trusts b, so we decrease a's score (a trusts someone, so a cannot be the judge)
# and increase b's score (b is trusted by someone).
# The judge is the one person whose final score equals n-1, meaning everyone else trusts them and they trust no one.

class Solution:
def findJudge(self, n: int, trust: List[List[int]]) -> int:
indegrees = [0] * (n + 1) # score for each person from 1 to n, index 0 is unused

for i in trust: # go through each trust pair
indegrees[i[0]] -= 1 # person i[0] trusts someone, so they lose a point (cannot be judge if they trust anyone)
indegrees[i[1]] += 1 # person i[1]] is trusted by someone, so they gain a point

for i in range(1, n + 1): # check every person from 1 to n
if indegrees[i] == n - 1: # trusted by everyone else and trusts nobody
return i # found the judge

return -1 # no one matches, no judge exists
46 changes: 46 additions & 0 deletions Problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Problem2 The Maze (https://leetcode.com/problems/the-maze/)
# Time Complexity: O(m * n * max(m, n)),Each cell can be visited once as a "stopping point" -> O(m*n) DFS calls.From each stopping point, we roll in 4 directions, each roll can take up to O(max(m,n)) steps
# Space Complexity: O(m * n),Recursion stack in the worst case can hold O(m*n) calls(the maze itself is reused as the visited array, so no extra visited grid is needed)
# Approach:
# The ball doesn't stop cell by cell, it rolls until it hits a wall or the border.
# So from each position, roll in all 4 directions until blocked, and only stop there.
# Treat each "stopping point" as a node, and DFS between stopping points.
# Mark visited stopping points as -1 in the maze to avoid revisiting the same paths.

class Solution:
def hasPath(self, maze, start, destination):
self.dirs = [(1,0),(0,1),(0,-1),(-1,0)] # down, right, left, up
self.m = len(maze) # number of rows
self.n = len(maze[0]) # number of columns

return self.dfs(maze, start[0], start[1], destination)

def dfs(self, maze, i, j, destination):
# base case 1: reached the destination
if destination[0] == i and destination[1] == j:
return True

# base case 2: already visited this stopping point, avoid infinite loop
if maze[i][j] == -1:
return False

maze[i][j] = -1 # mark current stopping point as visited

for dir in self.dirs:
r = dir[0] + i # take one step in this direction
c = dir[1] + j

# keep rolling while still inside the maze and not hitting a wall
while r >= 0 and c >= 0 and r < self.m and c < self.n and maze[r][c] != 1:
r += dir[0]
c += dir[1]

# the loop above overshoots by one step (lands on wall/border), so step back
r -= dir[0]
c -= dir[1]

# recursively check if the destination is reachable from this new stopping point
if self.dfs(maze, r, c, destination):
return True

return False # no direction led to the destination