Leecode207
题目
给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?
分析
由于有些课程存在学习的先决条件。所以可以得到:只要能满足各个课程的先决条件就能实现对所有课程的学习。所以可以得到若所有课程的先决条件相连后组成的图能组成环就代表无法达到条件,不能完成所有课程。
解法一
首先通过分析知道通过判断是否能组成环来得出结果。所以可以想到通过对其邻接矩阵进行操作来判断是否组成环。
public bool CanFinish(int numCourses, int[][] prerequisites) {
int [,] num=new int [numCourses,numCourses];
foreach(int[] item in prerequisites)
{
num[item[0],item[1]]=1;
}
for(int i=2;i<=numCourses;i++)
{
int[,] judge=new int [numCourses,numCourses];
for(int k=0;k<numCourses;k++)
{
judge[k,k]=1;
}
for(int j=1;j<i;j++)
{
int[,] op=judge;
for(int m=0;m<numCourses;m++)
{
for(int n=0;n<numCourses;n++)
{
int number=0;
for(int l=0;l<numCourses;l++)
{
number=number+op[m,l]*num[l,n];
}
judge[m,n]=number;
}
}
}
for(int k=0;k<numCourses;k++)
{
if(judge[k,k]>0)
{
return false;
}
}
}
return true;
}
}
这就是暴力的对邻接矩阵操作的代码,但是其时间复杂度过大,经常导致时间超出限制,因此就需要使用新的思路方法。
激发二
运用DFS。
代码:
public bool CanFinish(int numCourses, int[][] prerequisites) {
List<int>[] list = Enumerable.Range(0, numCourses).Select(c => new List<int>()). ToArray();
foreach (int[] item in prerequisites)
{
list[item[0]].Add(item[1]);
}
var trueList = new HashSet<int>();
for (int i = 0; i < numCourses; i++)
{
if (!DFS(trueList, new HashSet<int>(), list, i))
{
return false;
}
}
return true;
}
public bool DFS(HashSet<int> trueList, HashSet<int> used, List<int>[] list, int id)
{
if (trueList.Contains(id))
{
return true;
}
if (used.Contains(id))
{
return false;
}
else
{
used.Add(id);
}
foreach (int item in list[id])
{
if (DFS(trueList, used, list, item) == false)
{
return false;
}
}
trueList.Add(id);
return true;
}
效果: