Skip to content

Commit 5a67c5f

Browse files
author
wuduhren
committed
updates
1 parent dddf785 commit 5a67c5f

12 files changed

+355
-0
lines changed

problems/python3/clone-graph.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def cloneGraph(self, start: 'Node') -> 'Node':
3+
def dfs(node):
4+
if node in clones: return clones[node]
5+
6+
copy = Node(node.val)
7+
clones[node] = copy
8+
9+
for neighbor in node.neighbors:
10+
copy.neighbors.append(dfs(neighbor))
11+
12+
return clones[node]
13+
if not start: return start
14+
clones = {}
15+
dfs(start)
16+
return clones[start]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#Topological Sort
2+
class Solution:
3+
def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
4+
sortedCourse = []
5+
G = collections.defaultdict(list) #graph
6+
inbounds = collections.Counter()
7+
q = collections.deque()
8+
9+
#build graph
10+
for c1, c2 in prerequisites:
11+
G[c2].append(c1)
12+
inbounds[c1] += 1
13+
14+
#add the starting point to the q. (the ones that have 0 inbounds)
15+
for course in range(numCourses):
16+
if inbounds[course]==0: q.append(course)
17+
18+
#add the course that have 0 inbounds to the sortedCourse.
19+
#after that, imagine we remove it from the graph, so nextCourse inbound will -1
20+
#add to q if nextCourse have 0 inbounds
21+
while q:
22+
course = q.popleft()
23+
24+
sortedCourse.append(course)
25+
26+
for nextCourse in G[course]:
27+
inbounds[nextCourse] -= 1
28+
if inbounds[nextCourse]==0: q.append(nextCourse)
29+
30+
return sortedCourse if len(sortedCourse)==numCourses else []

problems/python3/course-schedule.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution:
2+
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
3+
sortedCourse = []
4+
inbounds = collections.Counter()
5+
G = collections.defaultdict(list)
6+
q = collections.deque()
7+
8+
for c1, c2 in prerequisites:
9+
G[c2].append(c1)
10+
inbounds[c1] += 1
11+
12+
for c in range(numCourses):
13+
if inbounds[c]==0: q.append(c)
14+
15+
while q:
16+
c = q.popleft()
17+
18+
for c2 in G[c]:
19+
inbounds[c2] -= 1
20+
if inbounds[c2]==0: q.append(c2)
21+
sortedCourse.append(c)
22+
23+
return len(sortedCourse)==numCourses
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class WordDictionary:
2+
3+
def __init__(self):
4+
self.root = {}
5+
6+
def addWord(self, word: str) -> None:
7+
node = self.root
8+
for c in word:
9+
if c not in node: node[c] = {}
10+
node = node[c]
11+
node['$'] = {} #'.' means the end of the word
12+
13+
def search(self, word: str) -> bool:
14+
def helper(node, i):
15+
if i==len(word): return '$' in node
16+
17+
if word[i]=='.':
18+
for c in node:
19+
if helper(node[c], i+1): return True
20+
return False
21+
else:
22+
if word[i] not in node: return False
23+
return helper(node[word[i]], i+1)
24+
return helper(self.root, 0)
25+
26+
27+
28+
29+
30+
31+
32+
33+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Trie:
2+
3+
def __init__(self):
4+
self.root = {}
5+
6+
def insert(self, word: str) -> None:
7+
node = self.root
8+
for c in word:
9+
if c not in node: node[c] = {}
10+
node = node[c]
11+
node['.'] = {} #'.' means the end of the word
12+
13+
14+
def search(self, word: str) -> bool:
15+
node = self.root
16+
for c in word:
17+
if c not in node: return False
18+
node = node[c]
19+
return '.' in node
20+
21+
def startsWith(self, prefix: str) -> bool:
22+
node = self.root
23+
for c in prefix:
24+
if c not in node: return False
25+
node = node[c]
26+
return True
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution:
2+
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
3+
def dfs(i, j) -> int:
4+
if i<0 or j<0 or i>=MAX_ROW or j>=MAX_COL: return 0
5+
if grid[i][j]==0 or grid[i][j]==2: return 0
6+
7+
grid[i][j] = 2 #mark as visited
8+
9+
area = 1
10+
area += dfs(i+1, j)
11+
area += dfs(i-1, j)
12+
area += dfs(i, j+1)
13+
area += dfs(i, j-1)
14+
return area
15+
16+
ans = 0
17+
MAX_ROW = len(grid)
18+
MAX_COL = len(grid[0])
19+
20+
for i in range(MAX_ROW):
21+
for j in range(MAX_COL):
22+
ans = max(ans, dfs(i, j))
23+
return ans

problems/python3/number-of-islands.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution:
2+
def numIslands(self, grid: List[List[str]]) -> int:
3+
def dfs(i, j):
4+
if i<0 or j<0 or i>=MAX_ROWS or j>=MAX_COLS: return
5+
if grid[i][j]!='1': return
6+
7+
grid[i][j] = '2'
8+
dfs(i+1, j)
9+
dfs(i-1, j)
10+
dfs(i, j+1)
11+
dfs(i, j-1)
12+
13+
count = 0
14+
MAX_ROWS = len(grid)
15+
MAX_COLS = len(grid[0])
16+
17+
for i in range(MAX_ROWS):
18+
for j in range(MAX_COLS):
19+
if grid[i][j]=='1':
20+
dfs(i, j)
21+
count += 1
22+
return count
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution:
2+
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
3+
def bfs(q, ocian):
4+
while q:
5+
i0, j0 = q.popleft()
6+
if (i0, j0) in ocian: continue
7+
ocian.add((i0, j0))
8+
9+
for i, j in ((i0+1, j0), (i0-1, j0), (i0, j0+1), (i0, j0-1)):
10+
if i<0 or j<0 or i>=MAX_ROW or j>=MAX_COL: continue
11+
if heights[i][j]>=heights[i0][j0]: q.append((i, j))
12+
13+
MAX_ROW = len(heights)
14+
MAX_COL = len(heights[0])
15+
16+
#add the top and left to q1
17+
pacific = set()
18+
q1 = collections.deque()
19+
for j in range(MAX_COL): q1.append((0, j))
20+
for i in range(MAX_ROW): q1.append((i, 0))
21+
22+
#add botton and right to q2
23+
atlantic = set()
24+
q2 = collections.deque()
25+
for j in range(MAX_COL): q2.append((MAX_ROW-1, j))
26+
for i in range(MAX_ROW): q2.append((i, MAX_COL-1))
27+
28+
bfs(q1, pacific)
29+
bfs(q2, atlantic)
30+
return pacific.intersection(atlantic)

problems/python3/rotting-oranges.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Solution:
2+
def orangesRotting(self, grid: List[List[int]]) -> int:
3+
time = 0
4+
rotten = set()
5+
aboutToRot = set()
6+
fresh = set()
7+
8+
for i in range(len(grid)):
9+
for j in range((len(grid[0]))):
10+
if grid[i][j]==2:
11+
rotten.add((i, j))
12+
elif grid[i][j]==1:
13+
fresh.add((i, j))
14+
15+
while rotten:
16+
i0, j0 = rotten.pop() #randomly get one
17+
grid[i0][j0] = 2
18+
19+
for i, j in ((i0+1, j0), (i0-1, j0), (i0, j0+1), (i0, j0-1)):
20+
if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]): continue
21+
if (i, j) in rotten or (i, j) in aboutToRot: continue
22+
if (i, j) in fresh:
23+
fresh.remove((i, j))
24+
aboutToRot.add((i, j))
25+
26+
if not rotten and not aboutToRot: break
27+
28+
if not rotten:
29+
time += 1
30+
rotten = aboutToRot
31+
aboutToRot = set()
32+
33+
if fresh: return -1
34+
35+
return time
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""
2+
Time: O(N)
3+
Space: O(N)
4+
"""
5+
class Solution:
6+
def solve(self, board: List[List[str]]) -> None:
7+
def dfs(i0, j0):
8+
if i0<0 or j0<0 or i0>=MAX_ROW or j0>=MAX_COL: return
9+
if board[i0][j0]!='O': return
10+
if (i0, j0) in survived: return
11+
12+
survived.add((i0, j0))
13+
dfs(i0+1, j0)
14+
dfs(i0-1, j0)
15+
dfs(i0, j0+1)
16+
dfs(i0, j0-1)
17+
18+
19+
MAX_ROW = len(board)
20+
MAX_COL = len(board[0])
21+
survived = set()
22+
23+
for i in range(MAX_ROW):
24+
dfs(i, 0)
25+
dfs(i, MAX_COL-1)
26+
27+
for j in range(MAX_COL):
28+
dfs(0, j)
29+
dfs(MAX_ROW-1, j)
30+
31+
for i in range(MAX_ROW):
32+
for j in range(MAX_COL):
33+
board[i][j] = 'O' if (i, j) in survived else 'X'
34+
return board

problems/python3/walls-and-gates.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution:
2+
def wallsAndGates(self, rooms: List[List[int]]) -> None:
3+
def bfs(i0, j0) -> None:
4+
q = collections.deque([(i0+1, j0, 1), (i0-1, j0, 1), (i0, j0+1, 1), (i0, j0-1, 1)])
5+
visited = set()
6+
7+
while q:
8+
i, j, dis = q.popleft()
9+
10+
if i<0 or j<0 or i>=MAX_ROW or j>=MAX_COL: continue
11+
if rooms[i][j]==0 or rooms[i][j]==-1: continue
12+
if (i, j, dis) in visited: continue
13+
visited.add((i, j, dis))
14+
15+
if dis<rooms[i][j]:
16+
rooms[i][j] = dis
17+
q.append((i+1, j, dis+1))
18+
q.append((i-1, j, dis+1))
19+
q.append((i, j+1, dis+1))
20+
q.append((i, j-1, dis+1))
21+
22+
MAX_ROW = len(rooms)
23+
MAX_COL = len(rooms[0])
24+
25+
for i in range(MAX_ROW):
26+
for j in range(MAX_COL):
27+
if rooms[i][j]==0:
28+
bfs(i, j)
29+
return rooms

problems/python3/word-search-ii.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
Time: O(M * 4 * 3^(L-1)), M is board elements count, L is the average word length.
3+
Space: O(N), N is the number of char in the words
4+
5+
This solution will TLE. We need to further "prune" the trie once we reach the leaf node.
6+
"""
7+
class TrieNode():
8+
def __init__(self):
9+
self.children = {}
10+
self.isEnd = False
11+
def addWord(self, word):
12+
curr = self
13+
for c in word:
14+
if c not in curr.children:
15+
curr.children[c] = TrieNode()
16+
curr = curr.children[c]
17+
curr.isEnd = True
18+
19+
class Solution:
20+
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
21+
def dfs(r, c, node, word):
22+
if c<0 or r<0 or c==COLS or r==ROWS: return
23+
if board[r][c] not in node.children: return
24+
if (r, c) in visited: return
25+
26+
visited.add((r, c))
27+
node = node.children[board[r][c]]
28+
word += board[r][c]
29+
if node.isEnd:
30+
ans.add(word)
31+
node.isEnd = False
32+
33+
dfs(r+1, c, node, word)
34+
dfs(r-1, c, node, word)
35+
dfs(r, c+1, node, word)
36+
dfs(r, c-1, node, word)
37+
38+
visited.remove((r, c))
39+
40+
41+
root = TrieNode()
42+
for word in words:
43+
root.addWord(word)
44+
45+
ROWS = len(board)
46+
COLS = len(board[0])
47+
48+
visited = set()
49+
ans = set()
50+
node = root
51+
for r in range(ROWS):
52+
for c in range(COLS):
53+
dfs(r, c, root, '')
54+
return ans

0 commit comments

Comments
 (0)