На самом деле ваша функция правильная, но такая неэффективная.
Это потому, что в cycle
функция выполняет так много избыточных операций, т.е. проверяет один и тот же узел несколько раз.
Ваш код:
bool cycle( vector<vector<int>> &adj,int i,vector<bool> vis){
if(vis[i])
return true;
vis[i] = true;
for(int k = 0; k < adj[i].size(); k++)
if(cycle(adj, adj[i][k], vis))
return true;
return false;
}
Пример:
0 ---> 1 ---> 2 ......... (some more edges)
0 ---> 3 ---> 2 ---> 4 ........ (some more edges)
Итак, для этого графика для начальной вершины 0
(с вашим кодом ) для функции bool
:
итерация - 1: вы выполняете DFS и проверяете 1
и 2
и ..... .
итерация - 2: вы выполняете DFS и проверяете 3
и снова 2
.....
Итак таким образом вы будете пересчитывать те же подзадачи. Чтобы избежать этого, вам нужно поместить другой массив, просто проверьте, вычислен ли уже узел.
Итак, я ввел еще один вектор var
(инициализированный как false), который в основном устанавливается в true, если node равен посещено и утверждено как нецикловый узел (который не входит в цикл).
Улучшено Код:
bool cycle( vector<vector<int>> &adj,int i,vector<bool> vis, vector<bool>& var){
// if i involves in cycle and visited in the current sequence
if(!var[i] and vis[i])
return true;
vis[i] = true;
for(int k=0;k<adj[i].size();k++) {
// if adj[i][k] is true i.e doesn't involve in cycle, so no need to check it. If it is false we should check it.
if(!var[adj[i][k]] and cycle(adj,adj[i][k],vis, var))
return true;
else
var[adj[i][k]] = true; // else setting true to tell it doesn't involve in cycle
}
// setting true to tell it doesn't involve in cycle
var[i] = true;
return false;
}
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> adj(numCourses);
for(int i=0;i<prerequisites.size();i++)
adj[prerequisites[i][1]].push_back(prerequisites[i][0]);
vector<bool> vis(numCourses,false);
vector<bool> var(numCourses,false);
for(int i=0;i<numCourses;i++)
if(cycle(adj,i,vis, var))
return false;
return true;
}
};
Примечание:
Я просто внес небольшие изменения, чтобы ваш код преодолел TLE, не меняя основы c logi c . Но это все еще неэффективно, так как ваш logi c должен передавать вектор по значению. Предлагаю вам подумать иначе :)