网站建设三折页,潮州哪里有做网站,wordpress 知乎,网站设计 seo课程表 力扣原题 你这个学期必须选修 numCourses 门课程#xff0c;记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出#xff0c;其中 prerequisites[i] [ai, bi] #xff0c;表示如果要学习课程 ai 则 必须 先学习课…课程表 力扣原题 你这个学期必须选修 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 。这是不可能的。 /*** param {number} numCourses* param {number[][]} prerequisites* return {boolean}*/
var canFinish function(numCourses, prerequisites) {// 构建节点关系 key: 当前节点 value当前节点指向的所有节点const edges buildEdges(prerequisites)let valid trueconst visited new Array(numCourses).fill(0)// 深度遍历判断是否存在环function dfs(i) {const edge edges[i]if(!edge) returnvisited[i] 1 // 访问中for(const nextNode of edge) {if(visited[nextNode] 0) {dfs(nextNode)if(!valid) return} else if(visited[nextNode] 1) {// 存在环valid false;return}}visited[i] 2; // 已访问}for(let i 0; i numCourses; i) {if(!visited[i]) {dfs(i)}}return valid
};// 构建边的关系
function buildEdges(prerequisites) {// 根据节点数量初始化所有的节点的相邻的空数组用于记录指向的节点const edgeMap {}for(const [node, preNode] of prerequisites) {if(!edgeMap[preNode]) {edgeMap[preNode] []}edgeMap[preNode].push(node)}return edgeMap
}
解题思路 核心思路是构建有向图然后深度遍历判断是否存在环存在环则无法进行拓扑排序也说明无法完成所有课程的学习 prerequisites中每一项表示[课程, 先修课程]。遍历prerequisites转化为key为先修课程value为课程的数组。[构建有向图]通过visited数组记录每个节点的访问状态0未访问1访问中2已访问遍历所有节点进行深度遍历dfs。深度遍历时只需要判断是否在遍历过程中遇到访问中的节点即可如果遇到访问中的节点证明存在环。(如果不存在环深度遍历过程中不可能访问到访问中的节点)