当前位置: 首页 > news >正文

【力扣1462】课程表(拓扑排序+bitset优化到O(n))

题目描述: 

你总共需要上 numCourses 门课,课程编号依次为 0 到 numCourses-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 = 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

分析思路

    首先看样例的图,大概率是图论题,再一个题目中有很明显的先后关系,所以可以锁定这个题是一道拓扑排序题。 当然这个题范围很小 n是100,Floyd的3层循环好像也能求解(类似传递闭包),代码应该更容易实现。 不过我想用bitset实现,那样的话 数据n如果开1e4(10000) 也没事, bitset的空间复杂度是(n*n/64).

   AC的过程还是有点艰难,之前写题没怎么用过vector,刚才初始化少加1 看了半天 o.O

因为题目编号范围是0~n-1,不太习惯,怕0这个数字会未知错误, 所以我给所有的编号都进行了+1处理

f[x][y]为1 表示x->y有边;  为0 表示无边   

class Solution {
public:vector<bool> checkIfPrerequisite(int numCourses, vector<vector<int>>& prerequisites, vector<vector<int>>& queries) {vector<int>d(numCourses+1);vector<vector<int>> edge(numCourses+1);for(vector<int> x:prerequisites){edge[x[0]+1].push_back(x[1]+1);//建边d[x[1]+1]++; //处理入度}queue<int>q;for(int i=1;i<=numCourses;i++){if(!d[i]){q.push(i);}}vector<int>ans;//ans里面存的是拓扑序列,注意:拓扑序列不是唯一的while(q.size()){int t=q.front();q.pop();ans.push_back(t);for(int x:edge[t]){if(--d[x]==0){q.push(x);}}}bitset<110>f[numCourses+1];for(int i=numCourses-1;i>=0;i--){int x=ans[i];for(int y:edge[x]){f[x][y]=1;f[x]|=f[y];//相当于位运算,时间复杂度是O(1)}}//处理答案vector<bool>ans1;for(auto x:queries){if(f[x[0]+1][x[1]+1])ans1.push_back(1);else ans1.push_back(0);}return ans1;}
};
http://www.lryc.cn/news/171058.html

相关文章:

  • 【AI】机器学习——支持向量机(非线性及分析)
  • 2023-09-20 LeetCode每日一题(拿硬币)
  • Java21的新特性
  • 测试-----selenuim webDriver
  • 21天学会C++:Day12----初始化列表
  • OpenAI开发系列(二):大语言模型发展史及Transformer架构详解
  • Gson - 一个Java序列化/反序列化库
  • 6-1 汉诺塔
  • Linux之initd管理系统(海思、ZYNQ、复旦微)添加密码登录验证
  • 怎么更改代理ip,代理ip如何切换使用?
  • 【C++从0到王者】第三十三站:AVL树
  • 手机机型响应式设置2
  • uni-app 之 解决u-button始终居中问题
  • Python日期处理库:掌握时间的艺术
  • JOSEF约瑟 智能电流继电器KWJL-20/L KWLD26 零序孔径45mm 柜内导轨式安装
  • NLP技术如何为搜索引擎赋能
  • 演唱会没买到票?VR直播为你弥补遗憾
  • myabtis的缓存级别
  • gin框架再探
  • 经典算法-----约瑟夫问题(C语言)
  • 代码随想录 动态规划Ⅴ
  • 驱动DAY9
  • 03贪心:摆动序列
  • javascript获取元素在浏览器中工作区域的左、右、上、下距离,或带滚动条的元素在页面中的大小
  • VSCode 安装使用教程 环境安装配置 保姆级教程
  • c盘中temp可以删除吗?appdata\local\temp可以删除吗?
  • Java手写聚类算法
  • 解密Java多线程中的锁机制:CAS与Synchronized的工作原理及优化策略
  • solid works草图绘制与设置零件特征的使用说明
  • vue3使用router.push()页面跳转后,该页面不刷新问题