LeetCode 1632. Rank Transform of a Matrix

題目

拖了兩個月,終於這這道題目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;

    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章