link: https://leetcode.com/problems/longest-increasing-path-in-a-matrix/
DP table紀錄第i,j個cell為起始點的increasing path最長長度,base case是四周鄰居都比自己小的cell,path長度包含自己所以是1,
用sort的方式找到matrix最大值,從最大值開始bottum up建立DP table。
class Solution:
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
dp = [[0] * n for _ in range(m)]
nums = sorted([(matrix[i][j], i, j)
for i in range(m)
for j in range(n)],
reverse=True)
ans = 1
for num, i, j in nums:
neighbors = [0]
for x, y in [[i-1, j], [i+1, j], [i, j-1], [i, j+1]]:
if 0 <= x < m and 0 <= y < n and num < matrix[x][y]:
neighbors.append(dp[x][y])
dp[i][j] = max(neighbors) + 1
ans = max(ans, dp[i][j])
return ans
更聰明點,直接用DFS來recursive找到base case。
class Solution:
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
dp = [[None] * n for _ in range(m)]
def dfs(i, j):
if dp[i][j] is None:
val = 0
for x, y in [[i-1, j], [i+1, j], [i, j-1], [i, j+1]]:
if 0 <= x < m and 0 <= y < n and matrix[i][j] < matrix[x][y]:
val = max(val, dfs(x, y))
dp[i][j] = val + 1
return dp[i][j]
path_length = 1
for i in range(m):
for j in range(n):
path_length = max(path_length, dfs(i, j))
return path_length
應用Kahn’s algorithm,先從indegree為0的cell出發,level-wise的做BFS,找出path的最長長度。
class Solution:
def longestIncreasingPath(self, matrix):
m, n = len(matrix), len(matrix[0])
# calculate indegree of all cells
indegree = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
for x, y in [[i-1, j], [i+1, j], [i, j-1], [i, j+1]]:
if 0 <= x < m and 0 <= y < n and matrix[i][j] > matrix[x][y]:
indegree[i][j] += 1
# start from cells whose indegree is 0
queue = deque()
for i in range(m):
for j in range(n):
if indegree[i][j] == 0:
queue.append((i,j))
# BFS
path_length = 0
while queue:
for _ in range(len(queue)):
i, j = queue.popleft()
for x, y in [[i-1, j], [i+1, j], [i, j-1], [i, j+1]]:
if 0 <= x < m and 0 <= y < n and matrix[i][j] < matrix[x][y]:
indegree[x][y] -= 1
if indegree[x][y] == 0:
queue.append((x, y))
path_length += 1
return path_length
leetcode
link: https://leetcode.com/problems/
Feb 9, 2024Difficulty: Easy link: https://leetcode.com/problems/linked-list-cycle/ 1. Hash table $O(n)$ runtime, $O(n)$ space 用set紀錄看過的node,如果有重複就代表有cycle。 python # Definition for singly-linked list. # class ListNode:
Dec 28, 2022Difficulty: Medium link: https://leetcode.com/problems/distribute-coins-in-binary-tree/ 1. DFS $O(N)$ runtime, $O(H)$ space 定義dfs函數,計算以node為root的subtree,扣掉每個child node需要的1枚硬幣後,總共會多(或少)幾枚硬幣。 如果硬幣有多,回傳值就是正的;如果硬幣有缺,回傳值就是負的;剛剛好不多不缺的情況,回傳值為0。 dfs函數顯示,node最少還需要幾枚硬幣(缺硬幣的情況),或著node至少要給出幾枚硬幣(多硬幣的情況),才能達成題目要求的硬幣分布。
Nov 26, 2022Difficulty: Medium link: https://leetcode.com/problems/permutations/ 1. Backtracking $O(n!)$ runtime, $O(n)$ space 需要列出所有排列數,可以用backtracking。用take紀錄有沒有拿過nums的第i個元素。 python class Solution: def permute(self, nums: List[int]) -> List[List[int]]:
Nov 26, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up