分析题目性质,因为操作次数无限,所以可以把所有可以交换的位置放到一起处理,对于每一个这样的连通块,肯定要把大的放前面,小的放后面。用并查集处理连通块.然后同一连通块倒序输出,就可以得到字典序最大的解,复杂度O(nlogn).
/** * struct Interval { * int start; * int end; * }; */ const int N = 1e5 + 10; int f[N], cnt[N]; vector<int> b[N]; int find(int x) { if(f[x] == x) return x; return f[x] = find(f[x]); } class Solution { public: /** * 返回最终得到的饮料排列 * @param n int整型 饮料数 * @param m int整型 数对的对数 * @param a Interval类vector 牛妹的数对 * @return int整型vector */ vector<int> sequence(int n, int m, vector<Interval>& a) { for(int i = 1; i <= n; i ++) f[i] = i; for(int i = 0; i < m; i ++) { int u = find(a[i].start); int v = find(a[i].end); f[u] = v; } vector<int> ans; for(int i = 1; i <= n; i ++) b[find(i)].push_back(i); for(int i = 1; i <= n; i ++) reverse(b[i].begin(), b[i].end()); for(int i = 1; i <= n; i ++) { int x = find(i); ans.push_back(b[x][cnt[x] ++]); } return ans; // write code here } };