classSolution: defminimumTime(self, n: int, relations: List[List[int]], time: List[int]) -> int: mx = 0 prev = [[] for _ inrange(n + 1)] for x, y in relations: prev[y].append(x) @lru_cache(None) defdp(i: int) -> int: cur = 0 for p in prev[i]: cur = max(cur, dp(p)) cur += time[i - 1] return cur for i inrange(1, n + 1): mx = max(mx, dp(i)) return mx
classSolution { publicintminimumTime(int n, int[][] relations, int[] time) { intmx=0; List<Integer>[] prev = newList[n + 1]; for (inti=0; i <= n; i++) { prev[i] = newArrayList<Integer>(); } for (int[] relation : relations) { intx= relation[0], y = relation[1]; prev[y].add(x); } Map<Integer, Integer> memo = newHashMap<Integer, Integer>(); for (inti=1; i <= n; i++) { mx = Math.max(mx, dp(i, time, prev, memo)); } return mx; }
publicintdp(int i, int[] time, List<Integer>[] prev, Map<Integer, Integer> memo) { if (!memo.containsKey(i)) { intcur=0; for (int p : prev[i]) { cur = Math.max(cur, dp(p, time, prev, memo)); } cur += time[i - 1]; memo.put(i, cur); } return memo.get(i); } }
publicclassSolution { publicintMinimumTime(int n, int[][] relations, int[] time) { int mx = 0; IList<int>[] prev = new IList<int>[n + 1]; for (int i = 0; i <= n; i++) { prev[i] = new List<int>(); } foreach (int[] relation in relations) { int x = relation[0], y = relation[1]; prev[y].Add(x); } IDictionary<int, int> memo = new Dictionary<int, int>(); for (int i = 1; i <= n; i++) { mx = Math.Max(mx, DP(i, time, prev, memo)); } return mx; }
publicintDP(int i, int[] time, IList<int>[] prev, IDictionary<int, int> memo) { if (!memo.ContainsKey(i)) { int cur = 0; foreach (int p in prev[i]) { cur = Math.Max(cur, DP(p, time, prev, memo)); } cur += time[i - 1]; memo.Add(i, cur); } return memo[i]; } }
funcminimumTime(n int, relations [][]int, time []int)int { res := 0 prev := make([][]int, n+1) for i := 0; i <= n; i++ { prev[i] = make([]int, 0) } for _, relation := range relations { x := relation[0] y := relation[1] prev[y] = append(prev[y], x) } memo := make(map[int]int) for i := 1; i <= n; i++ { res = max(res, dp(i, time, prev, memo)) } return res }
funcdp(i int, time []int, prev [][]int, memo map[int]int)int { if _, ok := memo[i]; !ok { cur := 0 for _, p := range prev[i] { cur = max(cur, dp(p, time, prev, memo)) } cur += time[i-1] memo[i] = cur } return memo[i] }
funcmax(a, b int)int { if a > b { return a } return b }
var minimumTime = function(n, relations, time) { let res = 0; let prev = Array(n + 1).fill(0); for (let i = 0; i <= n; i++) { prev[i] = []; } for (var relation of relations) { let x = relation[0], y = relation[1]; prev[y].push(x); } let memo = {}; for (let i = 1; i <= n; i++) { res = Math.max(res, dp(i, time, prev, memo)); } return res; };
functiondp(i, time, prev, memo) { if (!memo[i]) { let cur = 0; for (let p of prev[i]) { cur = Math.max(cur, dp(p, time, prev, memo)); } cur += time[i - 1]; memo[i] = cur; } return memo[i]; }
intdp(int i, constint *time, struct ListNode **prev, HashItem **memo) { if (!hashFindItem(memo, i)) { int cur = 0; for (struct ListNode *node = prev[i]; node != NULL; node = node->next) { int p = node->val; cur = fmax(cur, dp(p, time, prev, memo)); } cur += time[i - 1]; hashAddItem(memo, i, cur); } return hashGetItem(memo, i, 0); }
intminimumTime(int n, int** relations, int relationsSize, int* relationsColSize, int* time, int timeSize) { int mx = 0; structListNode *prev[n + 1]; for (int i = 0; i <= n; i++) { prev[i] = NULL; } for (int i = 0; i < relationsSize; i++) { int x = relations[i][0], y = relations[i][1]; structListNode *node = creatListNode(x); node->next = prev[y]; prev[y] = node; } HashItem *memo = NULL; for (int i = 1; i <= n; i++) { mx = fmax(mx, dp(i, time, prev, &memo)); } hashFree(&memo); for (int i = 0; i <= n; i++) { structListNode *node = prev[i]; while (node) { structListNode *cur = node; node = node->next; free(cur); } } return mx; }
复杂度分析
时间复杂度:O(m+n),其中 m 是数组 relations 长度。需要构建先修课邻接表,并且计算每个课程的最少月份数。因为每个课程只会被计算一次,因此相当于是每个 relation 会被遍历一次。