深度优先搜索
Posted 浮云神码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优先搜索相关的知识,希望对你有一定的参考价值。
今天发现对二叉树的搜索最好的方式还是递归, 虽说也是使用深度优先搜索的思想,但是主要是使用的虚拟机栈,在代码中没有很好的体现通过对栈的应用来完成深度优先搜索。今后对深度优先搜索的算法优先选取和图相关的题目。
来看今天的分享课程表。需了解 图中 顶点、入度的概念,本次的代码也有一点拓扑排序算法的影子。
/**
* https://leetcode-cn.com/problems/course-schedule
* 207. 课程表
* 难度 中等
* 你这个学期必须选修 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
*/
public class CourseSchedule {
public boolean canFinish(int numCourses, int[][] prerequisites) {
// degrees存储每个课程的入度(依赖多少门前置课程)
int[] degrees = new int[numCourses];
// edges 模拟有向边, 表示每个课程的后置课程集合
List<List<Integer>> edges = new ArrayList<>();
for (int i = 0; i < numCourses; i++) {
edges.add(new ArrayList<>());
}
// 遍历prerequisites
for (int[] preCourse : prerequisites) {
// preCourse[0]是依赖的一方, 所以入度要+1
degrees[preCourse[0]]++;
// preCourse[1]是被依赖的一方, 要将preCourse[0]添加到后置课程集合
edges.get(preCourse[1]).add(preCourse[0]);
}
// DFS 初始化栈, 存储所有入度为0的课程, 即不需要任何前置课程就能学习
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < numCourses; i++) {
if (degrees[i] == 0) {
stack.push(i);
}
}
while (!stack.isEmpty()) {
Integer currentNo = stack.pop();
List<Integer> dependencies = edges.get(currentNo);
for (Integer no : dependencies) {
// 将所有依赖课程的入度-1, 若等于0, 表示课程可以学习了, 则加入栈
if (--degrees[no] == 0) {
stack.push(no);
}
}
}
// 最终课程的入度都为0, 表示完成了所有课程的学习
for (int i : degrees) {
if (i > 0) {
return false;
}
}
return true;
}
}
以上是关于深度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章