【每日一题】力扣:课程表Ⅳ

课程表 IV

你总共需要上 numCourses 门课,课程编号依次为 0numCourses-1 。你会得到一个数组 prerequisite ,其中 prerequisites[i] = [ai, bi] 表示如果你想选 bi 课程,你必须先选 ai 课程。

先决条件也可以是 间接 的。如果课程 a 是课程 b 的先决条件,课程 b 是课程 c 的先决条件,那么课程 a 就是课程 c 的先决条件。

你也得到一个数组 queries ,其中 queries[j] = [uj, vj]。对于第 j 个查询,您应该回答课程 uj 是否是课程 vj 的先决条件。

返回一个布尔数组 answer ,其中 answer[j] 是第 j 个查询的答案。

思路及解析

  1. 首先,我们构建了一个课程依赖关系图 graph,其中每个节点代表一个课程,每个边表示一个课程的先修课程。我们遍历 prerequisites 中的先修课程关系,将这些关系添加到图中。

  2. 然后,我们创建了一个二维矩阵 dp,其中 dp[i][j] 表示课程 i 是否是课程 j 的先修课程。最初,所有的 dp[i][j] 都被初始化为 false

  3. 接下来,我们使用深度优先搜索来填充 dp 矩阵。我们从每个课程出发,尝试找到从当前课程到其他课程的所有可能路径,并在 dp 矩阵中标记这些课程之间的依赖关系。

  4. 最后,对于查询中的每一对课程 (x, y),我们检查 dp[y][x] 是否为 true。如果是 true,则表示课程 x 是课程 y 的先修课程,否则不是。

class Solution {
public:
    vector<bool> checkIfPrerequisite(int numCourses, vector<vector<int>>& prerequisites, vector<vector<int>>& queries) {
        vector<vector<int>> graph(numCourses, vector<int>());
        // 构建课程依赖关系图
        for (const auto& pre : prerequisites) {
            graph[pre[0]].push_back(pre[1]);
        }
        
        // 使用 dp[i][j] 表示 i 是否是 j 的先决条件
        vector<vector<bool>> dp(numCourses, vector<bool>(numCourses, false));
        for (int i = 0; i < numCourses; ++i) {
            dfs(i, i, graph, dp);
        }
        
        // 查询每一对课程是否有依赖关系
        vector<bool> answer;
        for (const auto& q : queries) {
            answer.push_back(dp[q[0]][q[1]]);
        }
        
        return answer;
    }
    
private:
    void dfs(int start, int cur, vector<vector<int>>& graph, vector<vector<bool>>& dp){
        for (int next : graph[cur]) {
            if (!dp[start][next]) {
                dp[start][next] = true;
                dfs(start, next, graph, dp);
            }
        }
    }
};
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skylar Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值