LeetCode207. 课程表

5 篇文章 0 订阅
2 篇文章 0 订阅

解题方法与 LeetCode210 相同

BFS方法

/*
 * 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
 *
 * 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi]
 * ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。
 *
 * 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
 * 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
 *
 *  
 *
 * 示例 1:
 *
 * 输入:numCourses = 2, prerequisites = [[1,0]]
 * 输出:true
 * 解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
 * 示例 2:
 *
 * 输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
 * 输出:false
 * 解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1
 * 。这是不可能的。  
 *
 * 提示:
 *
 * 1 <= numCourses <= 105
 * 0 <= prerequisites.length <= 5000
 * prerequisites[i].length == 2
 * 0 <= ai, bi < numCourses
 * prerequisites[i] 中的所有课程对 互不相同
 *
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode-cn.com/problems/course-schedule
 * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 */
class Solution {
private:
    vector<uint16_t> inDegree;  // -1 means take over; 0 means can take; othens mean cannot take.
    vector<vector<uint16_t>> edges;
    vector<uint16_t> result;

public:
    bool canFinish(int numCourses, vector<vector<int>> &prerequisites)
    {
        inDegree.resize(numCourses);
        edges.resize(numCourses);
        for (const auto &pair : prerequisites) {
            inDegree[pair[0]]++;
            edges[pair[1]].push_back(pair[0]);
        }

        bool goOn;
        do {
            goOn = false;
            for (auto i = 0; i < numCourses; i++) {
                if (inDegree[i] == 0) {
                    goOn = true;
                    result.push_back(i);
                    inDegree[i]--;
                    for (auto &item : edges[i]) {
                        inDegree[item]--;
                    }
                }
            }
        } while (goOn);
        return (result.size() == numCourses);
    }
};

DFS方法

/*
 * 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
 * 
 * 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。
 * 
 * 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
 * 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
 * 
 *  
 * 
 * 示例 1:
 * 
 * 输入:numCourses = 2, prerequisites = [[1,0]]
 * 输出:true
 * 解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
 * 示例 2:
 * 
 * 输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
 * 输出:false
 * 解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
 *  
 * 
 * 提示:
 * 
 * 1 <= numCourses <= 105
 * 0 <= prerequisites.length <= 5000
 * prerequisites[i].length == 2
 * 0 <= ai, bi < numCourses
 * prerequisites[i] 中的所有课程对 互不相同
 * 
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode-cn.com/problems/course-schedule
 * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 */

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>> &prerequisites)
    {
        edges.resize(numCourses);
        visit.resize(numCourses, NOT_VISIT);
        for (const auto &item : prerequisites) {
            edges[item[1]].push_back(item[0]);
        }

        for (int i = 0; i < numCourses; i++) {
            if (!dfs(i)) {
                return false;
            }
        }
        return true;
    }

private:
    enum state : uint8_t {
        NOT_VISIT,
        VISITING,
        VISITED,
    };
    vector<vector<int>> edges;
    vector<state> visit;

    bool dfs(int current)
    {
        if (visit[current] == VISITED) {
            return true;
        }
        if (visit[current] == VISITING) {
            return false;
        }

        visit[current] = VISITING;
        for (auto next : edges[current]) {
            if (!dfs(next)) {
                return false;
            }
        }
        visit[current] = VISITED;
        return true;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值