题解 | #牛牛吃水果的顺序# 拓扑排序 + 分层全排列
牛牛吃水果的顺序
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; } };