LeetCode 1605.给定行和列的和求可行矩阵

题目描述

给你两个非负整数数组 `rowSum 和 colSum` ,其中 `rowSum[i]` 是二维矩阵中第 i 行元素的和, `colSum[j]` 是第 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。

请找到大小为`rowSum.length` * `colSum.length` 的任意 非负整数 矩阵,且该矩阵满足 `rowSum` 和 `colSum` 的要求。

请你返回任意一个满足题目要求的二维矩阵,题目保证存在 至少一个 可行矩阵

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/find-valid-matrix-given-row-and-column-sums

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

贪心算法,每次设置元素的时候把它设置成可以用的最大值,即同时使得行和列都不超过上限的最大值`min(rowSum[i], colSum[j])`;同时把rowSum 和 colSum均减少已经设置的值表示该行/该列还剩下多少可以使用,0表示用完了

粗略考虑了一手这个做法的正确性:矩阵的自由度是, 但是给定行列的限制只有 $2*n$的自由度,虽然题目保证了一定有解,但不确定这样的做法是否一定可以得到正确结果。每次操作都会使得一行/一列的可用结果为0,或者使得已成0的行/列保持,因此只会在最后一个值可能遇到行和列剩余值不匹配的情况,但题目保证有解首先是要保证sum(rowSum)与sum(colSum)相等, 并且在每次操作的时候rowSum[i]和colSum[j]是同步减小的,因此到最后剩下的唯一非0元素也应该相等,所以是可以做出来

感觉起来正确性证明的过程就是循环不变量

Initialization :初始的时候 rowSum的和与colSum的和相等

Maintenance:每次迭代rowSum[i]和colSum[j]同步减少ret[i][j],上述两个和仍然相等

Termination :最后一次输入的数据要同时等于上述两个和,即只需要两个和相等即可。

代码

class Solution {
public:
    vector<vector<int>> restoreMatrix(vector<int>& rowSum, vector<int>& colSum) {
        int x = rowSum.size();
        int y = colSum.size();
        

        vector<vector<int>> ret;
        for(int i=0; i < x; i++){
            vector<int> row(y, 0);
            ret.push_back(row);
        }
        // printf("ret.size = %d, %d\n", ret.size(), ret[0].size());
        for(int i=0; i< x; i++){
            for(int j=0; j< y; j++){
                if(rowSum[i]< colSum[j]){
                    ret[i][j] = rowSum[i];
                else{
                    ret[i][j] = colSum[i];
                }
                rowSum[i] -= ret[i][j];
                colSum[j] -= ret[i][j];
            }
        }
        return ret;
    }
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值