题解 | #牛牛吃水果的顺序# 拓扑排序 + 分层全排列
牛牛吃水果的顺序
https://www.nowcoder.com/practice/336b43ff1d664cdd8e3e39acb67dfa39
知识点
拓扑排序 dfs 全排列
解题思路
首先很明显要进行拓扑排序来确定拓扑关系以及检查是否有环。在拓扑排序过程中,没有相互制约关系的两个元素可以互换位置,所以在同一层,有a->b这样的制约关系的需要b在a的下一层里,层内进行全排列后加入答案,实现过程中可以用dfs实现。
注意有环的时候没有合法解,返回空即可。
AC Code(C++)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numFruits int整型
* @param prerequisites int整型vector<vector<>>
* @return int整型vector<vector<>>
*/
using pii = pair<int, int>;
vector<vector<int> > findFruitOrder(int n, vector<vector<int> >& prerequisites) {
// retyrn
// toposort
vector<vector<int>> layer;
vector<int> d(n);
vector<vector<int>> g(n);
for (auto& p : prerequisites) {
int a = p[0], b = p[1];
g[b].push_back(a);
d[a] += 1;
}
queue<pii> q;
for (int i = 0; i < n; i ++) {
if (!d[i]) q.emplace(i, 0);
}
while (!q.empty()) {
auto [t, l] = q.front();
if (layer.size() <= l) layer.push_back({});
layer[l].emplace_back(t);
q.pop();
for (auto x: g[t]) {
if (--d[x] == 0) q.emplace(x, l + 1);
}
}
// 检查是否有环
for (int i = 0; i < n; i ++) {
if (d[i]) return {};
}
vector<vector<int>> res;
for (auto& v : layer) {
sort(v.begin(), v.end());
}
vector<int> path;
function<void(int)> dfs = [&](int u) {
if (u == layer.size()) {
res.push_back(path);
return;
}
int len = size(layer[u]);
do {
for (auto x : layer[u]) {
path.push_back(x);
}
dfs(u + 1);
for (int i = 0; i < len; i ++) path.pop_back();
} while (next_permutation(layer[u].begin(), layer[u].end()));
};
dfs(0);
return res;
}
};
