题目:

解答:
cpp
class Solution {
private:
vector<vector<int>> edges;
vector<int> inedge;
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
edges.resize(numCourses);
inedge.resize(numCourses);
for (int i = 0; i < prerequisites.size(); i++) {
vector<int> info = prerequisites[i]; //
edges[info[1]].push_back(info[0]);
inedge[info[0]]++;
}
queue<int> q;
for (int i = 0; i < numCourses; i++) {
if (inedge[i] == 0)
q.push(i);
}
int visit = 0;
while (!q.empty()) {
visit++;
int u = q.front();
q.pop();
vector<int> neig = edges[u]; //
for (int i = 0; i < neig.size(); i++) {
int v = neig[i];
inedge[v]--;
if (inedge[v] == 0)
q.push(v);
}
}
if (visit == numCourses)
return true;
else
return false;
}
};
心得:我原本误以为只要满足前者小于后者,必然不会出现环结构,但是这是非充分必要条件,所有有例外,卡了几个例子过不去。
答案采用拓扑排序的方法,将原一维数组的有效数据分别存储为入度数和入度边,再用于拓扑排序时的出队和入队。在vector<int> neig = edges[u];直接复制给neig是一种技巧。
题目:

解答:
cpp
class Solution {
public:
void backrack(vector<vector<int>>& res,vector<int>& output,int first,int lens){
if(first==lens){
res.emplace_back(output);
return;
}
for(int i=first;i<lens;i++){
swap(output[first],output[i]);
backrack(res,output,first+1,lens);
swap(output[i],output[first]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
int lens=nums.size();
backrack(res,nums,0,lens);
return res;
}
};
心得:这道题是回溯部分的题,用到了递归的方法,因为每次选数列中数字作为当前第一个,递归后面的排序,比如不会出现重复,得到的就是全部进行排列的结果。但因为每个都是O(n)的时间复杂度,总的为O(n!)。