Skip to content

Commit 79b9b8f

Browse files
author
wuduhren
committed
updates
1 parent 3af7236 commit 79b9b8f

9 files changed

+220
-0
lines changed

problems/python3/alien-dictionary.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Solution:
2+
def alienOrder(self, words: List[str]) -> str:
3+
adj = collections.defaultdict(list)
4+
inbounds = collections.Counter()
5+
q = collections.deque()
6+
ans = ''
7+
8+
adj = {c: set() for word in words for c in word}
9+
for i in range(len(words)-1):
10+
w1, w2 = words[i], words[i+1]
11+
minLen = min(len(w1), len(w2))
12+
if w1[:minLen]==w2[:minLen] and len(w1)>len(w2): return ""
13+
14+
for j in range(minLen):
15+
if w1[j]!=w2[j]:
16+
adj[w1[j]].add(w2[j])
17+
break
18+
19+
for c in adj:
20+
for nc in list(adj[c]):
21+
inbounds[nc] += 1
22+
23+
for c in adj:
24+
if inbounds[c]==0: q.append(c)
25+
26+
while q:
27+
c = q.popleft()
28+
29+
ans += c
30+
31+
for nc in adj[c]:
32+
inbounds[nc] -= 1
33+
if inbounds[nc]==0: q.append(nc)
34+
35+
return ans if len(ans)==len(adj) else ''
36+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Bellman-Ford.
3+
Time: O(KE)
4+
"""
5+
class Solution:
6+
def findCheapestPrice(self, N: int, flights: List[List[int]], src: int, dst: int, K: int) -> int:
7+
prices = {n:float('inf') for n in range(N)}
8+
prices[src] = 0
9+
10+
for k in range(K+1):
11+
temp = prices.copy()
12+
for source, destination, price in flights:
13+
if prices[source]==float('inf'): continue
14+
if prices[source]+price<temp[destination]:
15+
temp[destination] = prices[source]+price
16+
prices = temp
17+
return prices[dst] if prices[dst]!=float('inf') else -1

problems/python3/climbing-stairs.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def climbStairs(self, N: int) -> int:
3+
dp = [0]*(N+1)
4+
dp[0] = 1
5+
for i in range(len(dp)):
6+
if i-1>=0:
7+
dp[i] += dp[i-1]
8+
if i-2>=0:
9+
dp[i] += dp[i-2]
10+
return dp[-1]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
Time: O(N)
3+
Space: O(N), can further reduce to using only 2 variables -> O(1).
4+
5+
dp[i] := the cost to get to index i.
6+
"""
7+
class Solution:
8+
def minCostClimbingStairs(self, cost: List[int]) -> int:
9+
N = len(cost)
10+
dp = [float('inf')]*(N+1)
11+
dp[0] = 0
12+
dp[1] = 0
13+
14+
for i in range(2, len(dp)):
15+
dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2])
16+
return dp[-1]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution:
2+
def minCostConnectPoints(self, points: List[List[int]]) -> int:
3+
ans = 0
4+
visited = set()
5+
adj = collections.defaultdict(list)
6+
N = len(points)
7+
8+
#build adjacency list
9+
for i in range(N):
10+
x0, y0 = points[i]
11+
for j in range(i+1, N):
12+
x1, y1 = points[j]
13+
dis = abs(x0-x1)+abs(y0-y1)
14+
adj[(x0, y0)].append((dis, x1, y1))
15+
adj[(x1, y1)].append((dis, x0, y0))
16+
17+
h = [(0, points[0][0], points[0][1])] #min heap
18+
while len(visited)<N:
19+
dis, x, y = heapq.heappop(h)
20+
21+
if (x, y) in visited: continue
22+
visited.add((x, y))
23+
ans += dis
24+
25+
for dis1, x1, y1 in adj[(x, y)]:
26+
if (x1, y1) in visited: continue
27+
heapq.heappush(h, (dis1, x1, y1))
28+
return ans
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution:
2+
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
3+
ans = 0
4+
adj = collections.defaultdict(list)
5+
h = []
6+
visited = set()
7+
8+
for u, v, w in times:
9+
adj[u].append((v, w))
10+
11+
heapq.heappush(h, (0, k))
12+
while h:
13+
timeNeededToGetHere, node = heapq.heappop(h)
14+
15+
if node in visited: continue
16+
visited.add(node)
17+
ans = max(ans, timeNeededToGetHere)
18+
19+
for nei, time in adj[node]:
20+
if nei in visited: continue
21+
heapq.heappush(h, (time+timeNeededToGetHere, nei))
22+
23+
return ans if len(visited)==n else -1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
DFS with backtracking.
3+
"""
4+
class Solution:
5+
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
6+
def dfs(start) -> bool:
7+
if len(ans)==len(tickets)+1: return True
8+
if start not in adj: return False
9+
10+
temp = list(adj[start])
11+
for i, arr in enumerate(temp):
12+
adj[start].pop(i)
13+
ans.append(arr)
14+
if dfs(arr): return True
15+
adj[start].insert(i, arr)
16+
ans.pop()
17+
return False
18+
19+
ans = ['JFK']
20+
adj = collections.defaultdict(list)
21+
22+
tickets.sort()
23+
for des, arr in tickets:
24+
adj[des].append(arr)
25+
26+
dfs('JFK')
27+
return ans
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
Time: O(N^2 * LogN^2) = O(N^2 * 2LogN) = O(N^2LogN), N is the number of elements in a row or column.
3+
Space: O(N^2)
4+
"""
5+
class Solution:
6+
def swimInWater(self, grid: List[List[int]]) -> int:
7+
ROWS = len(grid)
8+
COLS = len(grid[0])
9+
10+
visited = set()
11+
h = [(grid[0][0], 0, 0)]
12+
13+
while h:
14+
t, r0, c0 = heapq.heappop(h)
15+
16+
if (r0, c0) in visited: continue
17+
visited.add((r0, c0))
18+
if r0==ROWS-1 and c0==COLS-1: return t
19+
20+
for r, c in ((r0+1, c0), (r0-1, c0), (r0, c0+1), (r0, c0-1)):
21+
if r<0 or c<0 or r>=ROWS or c>=COLS: continue
22+
if (r, c) in visited: continue
23+
heapq.heappush(h, (max(t, grid[r][c]), r, c))

problems/python3/word-ladder.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
Time: O(NxM^2). N is the number of words. M is the length of the word.
3+
Note that, getPatterns() takes O(M^2) since creating new string will also takes O(M) and for each word we do that O(M) times.
4+
5+
Space: O(NxM^2)
6+
"""
7+
class Solution:
8+
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
9+
def getPatterns(word) -> List[str]:
10+
patterns = []
11+
for i in range(len(word)):
12+
pattern = word[:i]+'*'+word[i+1:]
13+
patterns.append(pattern)
14+
return patterns
15+
16+
17+
if endWord not in wordList: return 0
18+
wordList.append(beginWord)
19+
20+
#build adjacency list
21+
nei = collections.defaultdict(list)
22+
for word in wordList:
23+
for pattern in getPatterns(word):
24+
nei[pattern].append(word)
25+
26+
#BFS
27+
q = collections.deque([(beginWord, 1)])
28+
visited = set()
29+
while q:
30+
word, steps = q.popleft()
31+
32+
if word in visited: continue
33+
visited.add(word)
34+
if word==endWord: return steps
35+
36+
for pattern in getPatterns(word):
37+
for nextWord in nei[pattern]:
38+
if nextWord in visited: continue
39+
q.append((nextWord, steps+1))
40+
return 0

0 commit comments

Comments
 (0)