力扣1462.课程表

简介: 力扣1462.课程表

题目描述:

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

  • 有的课会有直接的先修课程,比如如果想上课程 1 ,你必须先上课程 0 ,那么会以 [0,1] 数对的形式给出先修课程数对。

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

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

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

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]], queries = [[0,1],[1,0]]

输出:[false,true]

解释:课程 0 不是课程 1 的先修课程,但课程 1 是课程 0 的先修课程。

示例 2:

输入:numCourses = 2, prerequisites = [], queries = [[1,0],[0,1]]

输出:[false,false]

解释:没有先修课程对,所以每门课程之间是独立的。

示例 3:

输入:numCourses = 3, prerequisites = [[1,2],[1,0],[2,0]], queries = [[1,0],[1,2]]

输出:[true,true]


提示:

  • 2 <= numCourses <= 100
  • 0 <= prerequisites.length <= (numCourses * (numCourses - 1) / 2)
  • prerequisites[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi
  • 每一对 [ai, bi] 都 不同
  • 先修课程图中没有环。
  • 1 <= queries.length <= 104
  • 0 <= ui, vi <= n - 1
  • ui != vi

前言:

没错,又是课程表,只不过题目考的内容变了多了一点。理清题目的意思以及给的示例就要猜到这是一个有向图,又看到题目说没有环,那就容易想到拓扑图了。而且,题目中这种类似先决条件有强硬的顺序要求,容易考拓扑排序。

什么是拓扑排序?

对于任何有向图而言,其拓扑排序为其所有节点的一个线性排序(对于同一个有向图而言可能存在多个这样的节点排序)。该排序满足这样的条件:对于图中的任意两个节点u和v,若存在一条有向边从u指向v,则在拓扑排序中u一定出现在v前面。

举个例子:你的朋友来家里吃饭,你准备做饭,你要做饭,首先得买菜,买菜得去超市,去超市要出门搭车,因此这个顺序就是 出门搭车 -> 到超市 -> 买菜 -> 回家做饭

对于题目中的先决条件和间接条件也是一个道理,如果课程 a 是课程 b 的先决条件,课程 b 是课程 c 的先决条件,要想修课程c,那么就要先修课程b,而要想修课程吧,那么就要去修课程a。所以,修这三门课的拓扑顺序就是a-->b-->c,a一定在b的前面,b一定在c的前面。

思路:

由于题目要求的是对于第 j 个查询,回答课程 uj 是否是课程 vj 的先决条件。

我们可以建立一个邻接矩阵,f[a][b]表示a-->b这条边,返回类型为bool。f[a][b]表示a是b的先决条件。

那么在哪里去更新这个f[][]呢?

对于拓扑排序这个算法我们知道,每次在遍历一条边后都会把这条边删除,当遍历到t-->j这一条边,说明t是j的先决条件,也就是f[t][j]=true。那么我们可以再去遍历一遍所有到 j 的点,看看由f[t][j]能不能推出来其他的先决条件.

 
               f[t][j]=true;
               for(int h=0;h<numCourses;h++){
                   if(f[h][t]==true)f[h][j]=true;
               }

如果f[h][t]==true,说明h是t的先决条件,又由于f[t][j]=true,又能推出来f[h][j]=true.也就是当h-->t存在,t-->j存在,那么h-->j也存在。

由此,对于每一个点来说,每一个可以到这个点的边都可以被确认,这样一来,当我们把所有的边都遍历完后,可以确定的关系也就出来了。

代码:

public:
     int h[110],ne[10000],e[10000],idx;
     int d[110];
     int q[110];
     bool f[110][110];
     int hh=0,tt=-1;
     void add(int a,int b){
         e[idx]=b,ne[idx]=h[a],h[a]=idx++;
     }
 
 
    void topu(int numCourses){
       while(hh<=tt){
           int t=q[hh++];
 
           for(int i=h[t];i!=-1;i=ne[i]){
               int j=e[i];
 
               f[t][j]=true;
               for(int h=0;h<numCourses;h++){
                   if(f[h][t]==true)f[h][j]=true;
               }
               d[j]--;
               if(d[j]==0){
                   q[++tt]=j;
               }
           }
       }
    }
    vector<bool> checkIfPrerequisite(int numCourses, vector<vector<int>>& prerequisites, vector<vector<int>>& queries) {
 
       memset(h,-1,sizeof h);
       for(int i=0;i<numCourses;i++)d[i]=0;
       for(int i=0;i<10000;i++){
           ne[i]=0;
           e[i]=0;
       }
        for(auto it:prerequisites){
            int x=it[0];
            int y=it[1];
            add(x,y);
            d[y]++;
        }
        
        for(int i=0;i<numCourses;i++){
            if(d[i]==0){
                q[++tt]=i;
            }
        }
        topu(numCourses);
        vector<bool> ans;
       for(auto it:queries){
           int x=it[0];
           int y=it[1];
           
          ans.push_back(f[x][y]);
       }
        return ans;
    }


相关文章
|
19天前
|
Go
golang力扣leetcode 207.课程表
golang力扣leetcode 207.课程表
51 0
|
13天前
|
算法
力扣630.课程表
力扣630.课程表
|
19天前
|
存储 人工智能 BI
【力扣热题100】207. 课程表 python 拓扑排序
【力扣热题100】207. 课程表 python 拓扑排序
40 0
|
19天前
|
存储 人工智能 算法
☆打卡算法☆LeetCode 210. 课程表 II 算法解析
☆打卡算法☆LeetCode 210. 课程表 II 算法解析
|
19天前
|
存储 人工智能 算法
☆打卡算法☆LeetCode 207. 课程表 算法解析
☆打卡算法☆LeetCode 207. 课程表 算法解析
|
人工智能 Java BI
力扣207:课程表(Java拓扑排序:bfs+dfs)
力扣207:课程表(Java拓扑排序:bfs+dfs)
104 0
|
C++
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
50 0
【力扣·每日一题】630. 课程表 III (C++ 贪心 优先队列)
|
人工智能 算法 BI
Leetcode --- 课程表问题(拓扑排序)
Leetcode --- 课程表问题(拓扑排序)
|
人工智能 算法 BI
​LeetCode刷题实战210:课程表 II
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
137 0