LeetCode 1632. Rank Transform of a Matrix
阿新 • • 發佈:2020-12-30
拖了兩個月,終於這這道題目AC了。
思路是貪心,將所有的元素從小到大排序。並且維護兩個陣列,一個數組代表每一行的當前已經填上的最大的rank,比如nrank[0]=2 表示第0行,目前已經填到了rank=2,下一個再填就一定是>=2的數字。
同理列也是。一開始nrank[],和mrank[]都賦值為0。當我們貪心到一個元素的時候,它的rank,就是max(nrank[n], mrank[m])+1,
,
然後在遍歷所有元素的之前,我們需要用並查集把那些值相同並且行或者列相同的元素並起來,因為這些元素的rank值一定相同。
所以在並查集裡,被合併的元素集合裡的rank是集合rank最大的哪個元素的rank值。
所以實現就要把一個一個集合裡的所有元素都算出它的rank,對於每一個集合都取一個最大值。那麼怎麼算rank,就是max(nrank[n], mrank[m])+1。當一個集合的rank確定之後,
再把集合裡的所有元素的rank都填上,相應的nrank[] 和mrank[]也要改變。這個過程我們放到遍歷所有從小到大排好序的陣列中取實現。
最後終於過了。
還有一點,再遍歷之前的並查集操作,不能用N3的操作取並,只能N2*Log(N)
struct Node { int value; int x; int y; Node() {} Node(int x, int y, int value) { this->x = x; this->y = y; this->value = value; } }a[250005],b[505]; int compare(Node a, Node b) { return a.value < b.value; } class Solution { public: int n, m; int rrank[505][505]; int nrank[505][505]; int mrank[505][505]; int f[250005]; int v[250005]; int rn[505]; int rm[505]; int tag[505][505]; int find(int x) { if (f[x] != x) f[x] = find(f[x]); return f[x]; } void join(int x, int y) { int fx = find(x); int fy = find(y); f[fy] = fx; } vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) { n = matrix.size(); m = matrix[0].size(); int pos = 0; int pos2 = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { a[pos++] = Node(i, j, matrix[i][j]); } } sort(a, a + pos, compare); for (int i = 0; i < pos; i++) { tag[a[i].x][a[i].y] = i; f[i] = i; } for (int i = 0; i < n; i++) { pos2 = 0; for (int j = 0; j < m; j++) { b[pos2++] = Node(i, j, matrix[i][j]); } sort(b, b + pos2, compare); for (int j = 1; j < pos2; j++) { if (b[j].value != b[j - 1].value) { continue; } else { int fx = find(tag[i][b[j - 1].y]); int fy = find(tag[i][b[j].y]); f[fx] = fy; } } } for (int i = 0; i < m; i++) { pos2 = 0; for (int j = 0; j < n; j++) { b[pos2++] = Node(j, i, matrix[j][i]); } sort(b, b + pos2, compare); for (int j = 1; j < pos2; j++) { if (b[j].value != b[j - 1].value) { continue; } else { int fx = find(tag[b[j-1].x][i]); int fy = find(tag[b[j].x][i]); f[fx] = fy; } } } int start = 0; for (int i = 0; i < pos; i++) { int ran = max(rn[a[i].x], rm[a[i].y]) +1; int ff = find(i); if (v[ff] < ran) { v[ff] = ran; } if (i== pos-1 ||a[i + 1].value != a[i].value) { for (int j = start; j <= i; j++) { int xx = v[find(j)]; rrank[a[j].x][a[j].y] = xx; rn[a[j].x] = xx; rm[a[j].y] = xx; } start = i + 1; } } vector<vector<int>> ans; for (int i = 0; i < n; i++) { vector<int> res; for (int j = 0; j < m; j++) { res.push_back(rrank[i][j]); } ans.push_back(res); } return ans; } };