Leetcode 207 回溯法超时解决办法
代码1 为什么超时?
问题在于递归回溯函数中 vector<vector<int>> mp 没有添加 & 取地址,因为一开始考虑函数中并没有对入参进行修改,然而超时的原因就出现在这里:如果不取地址,每次递归操作会去复制一遍,加载到栈,这个操作会消耗时间,尤其是在此数据结构比较占地方比较复杂的时候尤甚;如果取了地址,每次会去访问同一个数据,不存在复制的时间消耗,如果算法复杂度不够好的时候,尤其要注意。
代码1:
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> mp(numCourses);
vector<int> search_path(numCourses);
for (int i = 0; i < prerequisites.size(); i++) {
mp[prerequisites[i][0]].push_back(prerequisites[i][1]);
}
for(int i = 0; i < numCourses; i++) {
if(!searchCricle(mp, i, search_path )) return false;
}
return true;
}
bool searchCricle(vector<vector<int>> mp, int i, vector<int> &search_path){
if(search_path[i] == -1) return true;
if(search_path[i] == 1) return false;
search_path[i] = 1;
for(auto k : mp[i]){
if(!searchCricle(mp, k, search_path)) return false;
}
search_path[i] = -1;
return true;
}
};
代码2却可以通过。
代码2:
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int> > adjacent(numCourses);
vector<int> flags(numCourses); //用于判断节点是否已经被访问
for(int i=0; i<prerequisites.size(); i++){
adjacent[prerequisites[i][0]].push_back(prerequisites[i][1]);
}
for(int i=0; i<numCourses; i++){
if(!DFS(i, adjacent, flags)) return false;
}
return true;
}
bool DFS(int i, vector<vector<int> > &adjacent, vector<int> &flags){
if(flags[i]==-1) return true;
if(flags[i]==1) return false;
flags[i]=1;
for(auto j:adjacent[i]){
if(!DFS(j, adjacent, flags)) return false;
}
flags[i]=-1;
return true;
}
};