6163. 给定条件下构造矩阵——每日一难(phase2_day1)

6163. 给定条件下构造矩阵

给你一个 正 整数 k ,同时给你:

  • 一个大小为 n 的二维整数数组 rowConditions ,其中 rowConditions[i] = [abovei, belowi]
  • 和 一个大小为 m 的二维整数数组 colConditions ,其中 colConditions[i] = [lefti,righti]

两个数组里的整数都是 1 到 k 之间的数字。

你需要构造一个 k x k 的矩阵,1 到 k 每个数字需要 恰好出现一次 。剩余的数字都是 0 。

矩阵还需要满足以下条件:

  • 对于所有 0 到 n - 1 之间的下标 i ,数字 abovei 所在的 行 必须在数字 belowi 所在行的上面。 对于所有 0 到
  • m - 1 之间的下标 i ,数字 lefti 所在的 列 必须在数字 righti 所在列的左边。 返回满足上述要求的 任意
    矩阵。如果不存在答案,返回一个空的矩阵。

示例 1:
https://leetcode.cn/problems/build-a-matrix-with-conditions/

输入:k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]]
输出:[[3,0,0],[0,0,1],[0,2,0]] 解释:上图为一个符合所有条件的矩阵。

行要求如下:
数字 1 在第 1 行,数字 2 在第 2 行,1 在 2 的上面。
数字 3 在第 0 行,数字 2 在第 2 行,3 在 2 的上面。
列要求如下:
数字 2 在第 1 列,数字 1 在第 2 列,2 在 1 的左边。
数字 3 在第 0 列,数字 2 在第 1 列,3 在 2 的左边。 注意,可能有多种正确的答案。

示例 2:

输入:k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]]
输出:[]
解释:由前两个条件可以得到 3 在 1 的下面,但第三个条件是 3 在 1 的上面。
没有符合条件的矩阵存在,所以我们返回空矩阵。

提示:

  • 2 <= k <= 400
  • 1 <= rowConditions.length, colConditions.length <= 1e4
  • rowConditions[i].length == colConditions[i].length == 2
  • 1 <= abovei,
  • belowi, lefti, righti <= k
  • abovei != belowi lefti != righti

解析:

  • 行与列分别处理
  • 可以数字之间的关系看成图的关系,入度越小优先级越高
  • 利用拓扑排序寻找优先级,如果有环就返回[]
  • 分别找到行、列的优先级之后,按照行关系将所有元素放置在每一行的最后一列(随便一列都行),然后根据列关系调整在每一行的具体列。

代码:

class Solution {
public:
    bool topological_sort(vector<int>& degrees,vector<int>& res,unordered_map<int,unordered_set<int>>& ums,int k){
        queue<int> zeros;
        for(int i=1;i<=k;i++){
            if(degrees[i]==0)
                zeros.push(i);
        }
        while(!zeros.empty()){
            auto a = zeros.front();
            zeros.pop();
            res.push_back(a);
            for(auto b : ums[a]){
                degrees[b]--;
                if(degrees[b]==0)
                    zeros.push(b);
            }
        }
        // 如果有点度数不为0,则res中放不了k个元素,说明有环
        return res.size()==k;   
    }
    vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) {
        vector<vector<int>> ans(k,vector<int>(k,0));
        vector<vector<int>> ans2;
        vector<int> degrees(k+1,0);
        int m=rowConditions.size();
        int n=colConditions.size();
        // 图结构,用unordered_map存储,set去除相同的边
        unordered_map<int,unordered_set<int>> ums;
        for(auto a : rowConditions){
            if(ums[a[0]].find(a[1])==ums[a[0]].end()){
                ums[a[0]].insert(a[1]);
                degrees[a[1]]++;
            } 
        }
        
        vector<int> res;
        // 如果有环返回[]
        if(!topological_sort(degrees,res,ums,k)){
            return ans2;
        }
       
		// 处理列
        vector<int> degrees2(k+1,0);
        unordered_map<int,unordered_set<int>> ums2;
        for(auto a : colConditions){
            if(ums2[a[0]].find(a[1])==ums2[a[0]].end()){
                ums2[a[0]].insert(a[1]);
                degrees2[a[1]]++;
            } 
        }
        vector<int> res2;
        if(!topological_sort(degrees2,res2,ums2,k)){
            return ans2;
        }

		// 先处理行,同时间记住每一个数字所在行下标
        unordered_map<int,int> pmap;
        for(int i=0;i<k;i++){
            ans[i][k-1]=res[i];
            pmap[res[i]]=i;
        }
        // 根据列关系调整列的位置
        for(int i=0;i<k;i++){
            int a = pmap[res2[i]];
            ans[a][k-1] = 0;
            ans[a][i] = res2[i];
        }
        return ans;
    }
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值