Build a Matrix With Conditions
Build a Matrix With Conditions
You are given a positive integer . You are also given:
- a 2D integer array of size where , and
- a 2D integer array of size where .
he two arrays contain integers from to .
You have to build a matrix that contains each of the numbers from to exactly once. The remaining cells should have the value .
The matrix should also satisfy the following conditions:
- The number should appear in a row that is strictly above the row at which the number appears for all from to .
- The number should appear in a column that is strictly left of the column at which the number appears for all from to .
Return any matrix that satisfies the conditions. If no answer exists, return an empty matrix.
Example 1:
Input: k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]] Output: [[3,0,0],[0,0,1],[0,2,0]] Explanation: The diagram above shows a valid example of a matrix that satisfies all the conditions. The row conditions are the following: - Number 1 is in row 1, and number 2 is in row 2, so 1 is above 2 in the matrix. - Number 3 is in row 0, and number 2 is in row 2, so 3 is above 2 in the matrix. The column conditions are the following: - Number 2 is in column 1, and number 1 is in column 2, so 2 is left of 1 in the matrix. - Number 3 is in column 0, and number 2 is in column 1, so 3 is left of 2 in the matrix. Note that there may be multiple correct answers.
Example 2:
Input: k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]] Output: [] Explanation: From the first two conditions, 3 has to be below 1 but the third conditions needs 3 to be above 1 to be satisfied. No matrix can satisfy all the conditions, so we return the empty matrix.
Constraints:
解题思路
比赛的时候思路都想出来了,就是拓扑排序,但代码就是没写出来,硬是调试了快一个小时也没写出来。
首先可以发现每个数字摆放在哪一行与哪一列是相互独立的,因此可以分别求每一行分别放哪些数,每一列分别放哪些数。
题目给的限制条件可以抽象出一个图,如果有,意味着要比大,那么就有一条从指向的边。把所有的限制条件建出图后对这个图跑一遍拓扑排序,看看有没有环。如果有环意味着之前给出的条件存在矛盾,等价于无解。如果没有环那么最后得到的拓扑序就是每个数字在答案矩阵中的行列坐标。
AC代码如下:
1 class Solution { 2 public: 3 int n; 4 5 vector<int> topsort(vector<vector<int>> &v) { 6 vector<vector<int>> g(n + 1); 7 vector<int> deg(n + 1); 8 for (auto &p : v) { 9 g[p[0]].push_back(p[1]); 10 deg[p[1]]++; 11 } 12 13 queue<int> q; 14 for (int i = 1; i <= n; i++) { 15 if (deg[i] == 0) q.push(i); 16 } 17 vector<int> ret; 18 while (!q.empty()) { 19 int t = q.front(); 20 q.pop(); 21 ret.push_back(t); 22 for (auto &it : g[t]) { 23 if (--deg[it] == 0) q.push(it); 24 } 25 } 26 27 return ret; 28 } 29 30 vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) { 31 n = k; 32 auto q1 = topsort(rowConditions); 33 auto q2 = topsort(colConditions); 34 if (q1.size() < n || q2.size() < n) return {}; 35 36 vector<vector<int>> ans(n, vector<int>(n)); 37 for (int i = 1; i <= n; i++) { 38 ans[find(q1.begin(), q1.end(), i) - q1.begin()][find(q2.begin(), q2.end(), i) - q2.begin()] = i; 39 } 40 return ans; 41 } 42 };
其实一开始看到这题我首先想到的是用floyd求传递闭包,时间复杂度是,大概率会超时,实际跑了一下确实会超时,不过这种做法是正确的。
一样根据约束条件建有向图,然后跑floyd求传递闭包,如果有矛盾的话此时必然存在某个数有,即有,这个肯定是有矛盾的。
TLE代码如下:
1 class Solution { 2 public: 3 int n; 4 5 vector<int> floyd(vector<vector<int>> &v) { 6 vector<vector<bool>> g(n + 1, vector<bool>(n + 1)); 7 for (auto &p : v) { 8 g[p[0]][p[1]] = true; 9 } 10 11 for (int k = 1; k <= n; k++) { 12 for (int i = 1; i <= n; i++) { 13 for (int j = 1; j <= n; j++) { 14 g[i][j] = g[i][j] | g[i][k] & g[k][j]; // leetcode上不知道为什么写成g[i][j] |= g[i][k] & g[k][j];会报错 15 } 16 } 17 } 18 19 for (int i = 1; i <= n; i++) { 20 if (g[i][i]) return {}; 21 } 22 23 vector<int> ret; 24 vector<bool> vis(n + 1); 25 for (int k = 1; k <= n; k++) { 26 int maxv = -1, idx; 27 for (int i = 1; i <= n; i++) { 28 if (!vis[i]) { 29 int t = 0; 30 for (int j = 1; j <= n; j++) { 31 if (!vis[j] && g[i][j]) t++; 32 } 33 if (t > maxv) maxv = t, idx = i; 34 } 35 } 36 ret.push_back(idx); 37 vis[idx] = true; 38 } 39 40 return ret; 41 } 42 43 vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) { 44 n = k; 45 auto q1 = floyd(rowConditions); 46 auto q2 = floyd(colConditions); 47 if (q1.empty() || q2.empty()) return {}; 48 49 vector<vector<int>> ans(n, vector<int>(n)); 50 for (int i = 1; i <= n; i++) { 51 ans[find(q1.begin(), q1.end(), i) - q1.begin()][find(q2.begin(), q2.end(), i) - q2.begin()] = i; 52 } 53 return ans; 54 } 55 };
参考资料
力扣第308场周赛:https://www.bilibili.com/video/BV1aW4y1t7Gd
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16632861.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效