知识点

拓扑排序 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;
    }
};