IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LC207. 课程表 -> 正文阅读

[数据结构与算法]LC207. 课程表

题目

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
提示:

1 <= numCourses <= 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有课程对 互不相同

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

思路

这是一道拓扑排序题。
想要判断能不能完成课,需要判断某些课程之间会不会形成一个有向环。如果有有向环,则说明无法完成规定的所有课程。

注意:

  • 对于课程x,它可能有多个前驱课程。
  • prerequisites没有出现的课程说明不需要前驱课程

对于一门课程能不能完成,我们需要查看它的前驱课程能不能完成。
比如[[1,2],[2,3][3,4]],想要知道课程1能不能完成,我们需要知道课程4能不能完成。
如果把上述结构看成一棵树,对于根节点1,我们就需要知道要找它的叶子节点,如果叶子节点均能正常完成,那么根节点也一定能完成。

根据这种思路来看,好像可以采用深度优先搜索来解决。即对于每个课程,判断它的叶子节点能不能完成,如果能完成,再从叶子节点一层一层往上推,直到根节点课程。
同时每次判断可以完成的课程,建立一个备忘录记下他们。这样,后面有些课程进行前驱判断时,可以依照这个备忘录排除一些课程,避免一些子树的重复搜索(也就是借助dp的思想)

代码流程如下:

  • 建立相应的标记数据结构:
    • pre数组:记录每个课程i的所有直接相连的前驱课程(如果用哈希表记录,会超时)
    • f数组:判断课程i是在哪种状态
      • 还没进行判断
      • 前驱节点判断中
      • 标记为可以完成的课程
    • valid:标记是否可以完成所有课程
  • 遍历0到numCourses-1的所有课程,如果他还没有进行判断,则进入dfs搜索
  • 当课程x进入搜索时,首先将f[x]标记为1,表示正在判断中。然后遍历x的所有前驱课程,对于每个前驱课程:
    • 如果没有被判断过,则dfs
    • 如果前驱节点也正在判断中,说明进入了有向环,课程无法完成,valid为false,结束。

代码

class Solution {
public:
    //采用哈希表会超时
    vector<vector<int>> pre;
    vector<int> f;
    bool valid = true;
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        pre.resize(numCourses);
        f.resize(numCourses);
        for(auto nums:prerequisites){
            pre[nums[0]].push_back(nums[1]);
        }
        for(int i=0;i<numCourses&&valid;i++){
            if(f[i]==0)
                dfs(i);
        }
        return valid;
    }
    void dfs(int x){
    	//1表示正在搜索它的前驱
        f[x] = 1;
        for(int i=0;i<pre[x].size();i++){
            if(f[pre[x][i]]==0)
                dfs(pre[x][i]);
            if(f[pre[x][i]]==1){
                valid = false;
                return;
            }
        }
        //2表示这门课可以顺利完成
        f[x] = 2;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:22:01  更:2022-03-06 13:27:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:42:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码