zoukankan      html  css  js  c++  java
  • leetcode1632 矩阵转换后的秩

    思路:

    整体思路是将矩阵中每个元素当作一个点,根据大小关系构造有向图之后进行拓扑排序。由于题目要求每一行(列)中相等的元素的秩要相等,所以在建图的时候考虑把这样的元素对应的点合并成一个点。具体实现使用并查集或者强连通分量缩点都可以。

    实现1(并查集):

     1 class Solution
     2 {
     3 public:
     4     int find(int x, vector<int>& p)
     5     {
     6         if (x == p[x]) return x;
     7         return p[x] = find(p[x], p);
     8     }
     9     void uni(int x, int y, vector<int>& p)
    10     {
    11         x = find(x, p); y = find(y, p);
    12         if (x != y) p[x] = y;
    13     }
    14     vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix)
    15     {
    16         int n = matrix.size(), m = matrix[0].size();
    17         vector<vector<int>> res(n, vector<int>(m, 0));
    18         vector<int> p(n * m);
    19         for (int i = 0; i < n * m; i++) p[i] = i;
    20         vector<vector<int>> g(n * m, vector<int>());
    21         vector<pair<int, int>> add;
    22         for (int i = 0; i < n; i++)
    23         {
    24             vector<pair<int, int>> v;
    25             for (int j = 0; j < matrix[i].size(); j++)
    26             {
    27                 v.push_back(make_pair(matrix[i][j], i * m + j));
    28             }
    29             sort(v.begin(), v.end());
    30             for (int j = 0; j < v.size() - 1; j++)
    31             {
    32                 int id = v[j].second, nid = v[j + 1].second; 
    33                 if (v[j].first == v[j + 1].first) uni(id, nid, p);
    34                 else add.push_back(make_pair(id, nid));
    35             }
    36         }
    37         for (int j = 0; j < m; j++)
    38         {
    39             vector<pair<int, int>> v;
    40             for (int i = 0; i < n; i++)
    41             {
    42                 v.push_back(make_pair(matrix[i][j], i * m + j));
    43             }
    44             sort(v.begin(), v.end());
    45             for (int i = 0; i < v.size() - 1; i++)
    46             {
    47                 int id = v[i].second, nid = v[i + 1].second;
    48                 if (v[i].first == v[i + 1].first) uni(id, nid, p);
    49                 else add.push_back(make_pair(id, nid));
    50             }
    51         }
    52         for (auto it: add)
    53         {
    54             int s = it.first, t = it.second;
    55             s = find(s, p); t = find(t, p);
    56             g[s].push_back(t);
    57         }
    58         vector<int> ind(n * m, 0);
    59         for (int i = 0; i < n * m; i++)
    60         {
    61             for (int j = 0; j < g[i].size(); j++)
    62             {
    63                 ind[g[i][j]]++;
    64             }
    65         }
    66         queue<pair<int, int>> q;
    67         for (int i = 0; i < n * m; i++)
    68         {
    69             if (ind[i] == 0) q.push(make_pair(i, 1));
    70         }
    71         vector<int> rank_p(n * m, 0);
    72         while (!q.empty())
    73         {
    74             pair<int, int> tmp = q.front(); q.pop();
    75             int id = tmp.first;
    76             int x = id / m, y = id % m;
    77             int r = tmp.second;
    78             int pa = find(id, p);
    79             rank_p[pa] = max(rank_p[pa], r);
    80             for (int i = 0; i < g[id].size(); i++)
    81             {
    82                 int e = g[id][i];
    83                 ind[e]--;
    84                 if (ind[e] == 0) q.push(make_pair(e, r + 1));
    85             }
    86         }
    87         for (int i = 0; i < n; i++) 
    88         {
    89             for (int j = 0; j < m; j++)
    90             {
    91                 int id = i * m + j;
    92                 int pa = find(id, p);
    93                 res[i][j] = rank_p[pa];
    94             }
    95         }
    96         return res;
    97     }
    98 };

    实现2(强连通分量缩点):

      1 class Solution
      2 {
      3 public:
      4     void add_edge(int x, int y, vector<vector<int>>& G, vector<vector<int>>& rG)
      5     {
      6         G[x].push_back(y); rG[y].push_back(x);
      7     }
      8     void dfs(int x, vector<vector<int>>& G, vector<int>& used, vector<int>& vs)
      9     {
     10         used[x] = 1;
     11         for (int i = 0; i < G[x].size(); i++)
     12         {
     13             int t = G[x][i];
     14             if (!used[t]) dfs(t, G, used, vs);
     15         }
     16         vs.push_back(x);
     17     }
     18     void rdfs(int x, vector<vector<int>>& rG, vector<int>& used, vector<int>& cmp, int cmp_id)
     19     {
     20         used[x] = 1;
     21         cmp[x] = cmp_id;
     22         for (int i = 0; i < rG[x].size(); i++)
     23         {
     24             int t = rG[x][i];
     25             if (!used[t]) rdfs(t, rG, used, cmp, cmp_id);
     26         }
     27     }
     28     void construct_graph(vector<pair<int, int>>& v, vector<vector<int>>& G, vector<vector<int>>& rG)
     29     {
     30         sort(v.begin(), v.end());
     31         int n = v.size();
     32         for (int i = 0; i < n; i++)
     33         {
     34             int j = i;
     35             while (j < n and v[j].first == v[i].first) j++;
     36             for (int k = i; k < min(j, n - 1); k++)
     37             {
     38                 add_edge(v[k].second, v[k + 1].second, G, rG);
     39             }
     40             if (j - i >= 2)
     41             {
     42                 add_edge(v[j - 1].second, v[i].second, G, rG);
     43             }
     44             i = j - 1;
     45         }
     46     }
     47     pair<vector<vector<int>>, vector<int>> scc(vector<vector<int>>& matrix)
     48     {
     49         int n = matrix.size(), m = matrix[0].size();
     50         vector<vector<int>> G(n * m, vector<int>()), rG(n * m, vector<int>());
     51         for (int i = 0; i < n; i++)
     52         {
     53             vector<pair<int, int>> v;
     54             for (int j = 0; j < m; j++)
     55             {
     56                 v.push_back(make_pair(matrix[i][j], i * m + j));
     57             }
     58             construct_graph(v, G, rG);
     59         }
     60         for (int j = 0; j < m; j++)
     61         {
     62             vector<pair<int, int>> v;
     63             for (int i = 0; i < n; i++)
     64             {
     65                 v.push_back(make_pair(matrix[i][j], i * m + j));
     66             }
     67             construct_graph(v, G, rG);
     68         }
     69         vector<int> vs, used(n * m, 0);
     70         for (int i = 0; i < n * m; i++)
     71         {
     72             if (!used[i]) dfs(i, G, used, vs);
     73         }
     74         fill(used.begin(), used.end(), 0);
     75         vector<int> cmp(n * m, -1);
     76         int cnt = 0;
     77         for (int i = vs.size() - 1; i >= 0; i--)
     78         {
     79             if (!used[vs[i]]) rdfs(vs[i], rG, used, cmp, cnt++);
     80         }
     81         vector<vector<int>> g(cnt, vector<int>());
     82         for (int i = 0; i < n * m; i++)
     83         {
     84             int x = cmp[i];
     85             if (x == -1) continue;
     86             for (int j = 0; j < G[i].size(); j++)
     87             {
     88                 int t = G[i][j];
     89                 int y = cmp[t];
     90                 if (x == y) continue;
     91                 g[x].push_back(y);
     92             }
     93         }
     94         return make_pair(g, cmp);
     95     }
     96     vector<int> toposort(vector<vector<int>>& g)
     97     {
     98         int n = g.size();
     99         vector<int> ind(n, 0);
    100         for (int i = 0; i < n; i++)
    101         {
    102             for (int j = 0; j < g[i].size(); j++)
    103             {
    104                 int t = g[i][j];
    105                 ind[t]++;
    106             }
    107         }
    108         queue<pair<int, int>> q;
    109         for (int i = 0; i < n; i++)
    110         {
    111             if (ind[i] == 0) q.push(make_pair(i, 1));
    112         }
    113         vector<int> rank(n, 0);
    114         while (!q.empty())
    115         {
    116             pair<int, int> tmp = q.front(); q.pop();
    117             int p = tmp.first, r = tmp.second;
    118             rank[p] = max(rank[p], r);
    119             for (int i = 0; i < g[p].size(); i++)
    120             {
    121                 int e = g[p][i];
    122                 ind[e]--;
    123                 if (ind[e] == 0) q.push(make_pair(e, r + 1));
    124             }
    125         }
    126         return rank;
    127     }
    128     vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix)
    129     {
    130         auto tmp = scc(matrix);
    131         auto g = tmp.first;
    132         auto cmp = tmp.second;
    133         auto rank = toposort(g);
    134         int n = matrix.size(), m = matrix[0].size();
    135         vector<vector<int>> res(n, vector<int>(m, 0));
    136         for (int i = 0; i < n; i++) 
    137         {
    138             for (int j = 0; j < m; j++)
    139             {
    140                 int p = i * m + j;
    141                 int cmp_id = cmp[p];
    142                 res[i][j] = rank[cmp_id];
    143             }
    144         }
    145         return res;
    146     }
    147 };
  • 相关阅读:
    Win10 下使用 ionic 框架开发 android 应用之搭载开发环境
    C# 图片压缩
    [安卓应用发布]HOLO一键锁屏
    SRS中增加身份验证
    实际搭建SRS测试的初步问题总结
    推荐一款优秀的开源流媒体服务器系统:SRS(Simple RTMP Server)
    C#--格式化数值数据
    操作系统学习笔记系列(二)-操作系统结构
    操作系统学习笔记系列(一)- 导论
    C语言文件读写
  • 原文地址:https://www.cnblogs.com/wangyiming/p/14354740.html
Copyright © 2011-2022 走看看