课程表题目的思路探讨与源码
课程表的题目如下图,该题属于搜索和图类型的题目,主要考察对于深度优先搜索DFS和广度优先搜索BFS的使用和理解。本文的题目作者想到2种方法,分别是深度优先搜索方法DFS和广度优先搜索方法BFS,其中广度优先搜索方法BFS使用java进行编写,而深度优先搜索方法DFS使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用广度优先搜索BFS的算法,首先初始化课程的数组和一个保存遍历信息的队列,然后初始化一个矩阵,把矩阵的每个值填充为一个空列表。然后开始访问课程列表,计算每个课程的入度度数,然后把入度度数的值保存在矩阵里。然后开始遍历课程输密码,把那些入度是0的元素加入到队列里。然后开始遍历队列,把队列的值从头开始拿出,然后用这个值去矩阵里面找到的列表进行遍历,如果入度度数是0,那么就把这个元素加入到列表末尾,否则就不操作。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
int[] degArr = new int[numCourses];
Queue<Integer> extraList = new LinkedList<>();
List<List<Integer>> matrix = new ArrayList<>();
for(int ir = 0; ir < numCourses; ir++)
matrix.add(new ArrayList<>());
for(int[] idx:prerequisites) {
degArr[idx[0]]=degArr[idx[0]]+1;
matrix.get(idx[1]).add(idx[0]);
}
for(int jr = 0; jr < numCourses; jr++)
if(degArr[jr] == 0){
extraList.add(jr);
}
while(! extraList.isEmpty()) {
int num = extraList.poll();
numCourses=numCourses-1;
for(int ind : matrix.get(num))
if(--degArr[ind]==0){
extraList.add(ind);
}
}
return numCourses == 0;
}
}
显然,我们还可以使用深度优先搜索DFS进行处理,首先我们把矩阵值和课程列表都进行初始化,然后把课程信息保存在矩阵里,然后调用深度优先方法进行搜索,在函数内部,主要是通过递归去判断,当前节点是否有环,或者被其他节点访问,如果是,则直接返回False,否则就继续循环遍历。所以根据这个思路就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
def dfsSearch(ir,matrix,sig):
if(sig[ir]==-1):
return True
if(sig[ir]==1):
return False
sig[ir]=1
for jr in matrix[ir]:
if(not dfsSearch(jr,matrix,sig)):
return False
sig[ir]=-1
return True
matrix = [[] for _ in range(numCourses)]
sig = [0 for _ in range(numCourses)]
for ind,num in prerequisites:
matrix[num].append(ind)
for kr in range(numCourses):
if(not dfsSearch(kr,matrix,sig)):
return False
return True
从结果来说java版本的广度优先搜索方法和python版本的深度优先搜索方法的速度都比较一般,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。