classSolution { structUF { vector<int> parent; int count; UF(int n) : parent(n), count(n) { iota(parent.begin(), parent.end(), 0); } // A utility function to find the subset of an element i intfind(int x) { return x == parent[x] ? x : parent[x] = find(parent[x]); }
// A utility function to do union of two subsets voidunite(int x, int y) { int xset = find(x); int yset = find(y); if(xset != yset) { parent[xset] = yset; --count; } } }; public: vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) { constint m = matrix.size(); constint n = matrix[0].size(); vector<int> rowsRank(m, 0); vector<int> colsRank(n, 0); vector<vector<int>> ans(m, vector<int>(n, 0)); using pii = pair<int, int>; map<int, vector<pii>> arr; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { arr[matrix[i][j]].emplace_back(i, j); } } for (constauto & p : arr) { constauto & v = p.second; constint vsize = v.size(); UF uf(vsize); vector<int> rowsIndex(m, -1); vector<int> colsIndex(n, -1); for (int i = 0; i < vsize; ++i) { auto [x, y] = v[i]; if (rowsIndex[x] == -1 && colsIndex[y] == -1) { rowsIndex[x] = i; colsIndex[y] = i; } elseif (rowsIndex[x] == -1) { rowsIndex[x] = i; uf.unite(i, colsIndex[y]); } elseif (colsIndex[y] == -1) { colsIndex[y] = i; uf.unite(i, rowsIndex[x]); } else { uf.unite(i, rowsIndex[x]); uf.unite(i, colsIndex[y]); } } unordered_map<int, vector<int>> cluster; for (int i = 0; i < vsize; ++i) { cluster[uf.find(i)].push_back(i); } for (constauto& p : cluster) { constauto& vec = p.second; int maxRank = numeric_limits<int>::min(); for (int i : vec) { maxRank = max(rowsRank[v[i].first] + 1, maxRank); maxRank = max(colsRank[v[i].second] + 1, maxRank); } for (int i : vec) { rowsRank[v[i].first] = maxRank; colsRank[v[i].second] = maxRank; ans[v[i].first][v[i].second] = maxRank; } } } return ans; } };