算法

2050. 并行课程 III

2023-07-31  本文已影响0人  红与树

题目

参考2050. 并行课程 III,难度分2084。

解题思路

记忆化搜索

class Solution {
    public int minimumTime(int n, int[][] relations, int[] time) {
        //一有没有先修课程(入度为0)的课程就开始学习,因为可以同时学习任意课程
        //构建图(HashMap或数组列表) 入度
        List<Integer>[] in = new List[n+1];
        for(int[] r : relations) {
            int pre = r[0], next = r[1];
            if(in[next] == null) in[next] = new ArrayList<Integer>();
            in[next].add(pre);
        }
        //动态规划思想 dp[i]表示学完课程i所需最少时间 
        //转移方程 dp[i] = max(dp[in[i]]) + time[i-1]//课程i的入度最少时间的最大值+课程i的时间
        //使用记忆化搜索 
        int ans = 0;
        int[] memo = new int[n+1];
        for(int i = 1; i <= n; i++) ans = Math.max(ans,dp(i, in, time, memo));
        return ans;
    }
    int dp(int i, List<Integer>[] in, int[] time, int[] memo) {
        if(in[i] == null || in[i].size() == 0) return time[i-1];
        if(memo[i] != 0) return memo[i];
        int cur = 0;
        for(int c : in[i]) {
            cur = Math.max(cur,dp(c, in, time, memo));
        }
        return memo[i] = cur + time[i-1];
    }
}

复杂度分析

拓扑排序+广度优先搜索

class Solution {
    public int minimumTime(int n, int[][] relations, int[] time) {
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        var deg = new int[n];
        for (var r : relations) {
            int x = r[0] - 1, y = r[1] - 1;
            g[x].add(y);
            deg[y]++;
        }
        var q = new ArrayDeque<Integer>();
        for (int i = 0; i < n; i++)
            if (deg[i] == 0)  q.add(i); // 没有先修课
        var f = new int[n];//定义f[i]表示完成第 i 门课程的最少月份数 (dp[i])
        int ans = 0;
        while (!q.isEmpty()) {
            int x = q.poll(); // x 出队,意味着 x 的所有先修课都上完了
            f[x] += time[x]; // 更新f[x] 加上当前课程的时间,就得到了最终的 f[x]
            ans = Math.max(ans, f[x]);//结果取最大
            for (int y : g[x]) { // 遍历 x 的邻居 y (出边)
                f[y] = Math.max(f[y], f[x]); // 更新 f[y] 的所有先修课程耗时的最大值 此时不用管time[y]
                if (--deg[y] == 0) q.add(y); // 入度为零加入队列
            }
        }
        return ans;
    }
}

复杂度分析

上一篇 下一篇

猜你喜欢

热点阅读