给定行和列的和求可行矩阵

题目描述:

给你两个非负整数数组 rowSum 和 colSum ,其中 rowSum[i] 是二维矩阵中前 i 行元素的和, colSum[j] 是前 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。请注意,这里是前 i 项,而不是Leetcode上的第 i 项。
请找到大小为 rowSum.length x colSum.length 的任意 非负整数 矩阵且该矩阵满足 rowSum 和 colSum 的要求。
其中1<=rowSum.length<=20,1<=colSum.length<=20,所有矩阵元素的范围为 [ 1 , 20 ] 。请你返回任意一个满足题目要求的二维矩阵,题目保证存在至少一个可行矩阵。


示例

输入:rowSum = [3,8], colSum = [4,7]
输出:
[[3,0],
[1,7]]
解释:
第 0 行:3 + 0 = 3 == rowSum[0]
第 1 行:1 + 7 = 8 == rowSum[1]
第 0 列:3 + 1 = 4 == colSum[0]
第 1 列:0 + 7 = 7 == colSum[1]
行和列的和都满足题目要求,且所有矩阵元素都是非负的。
另一个可行的矩阵为:
[[1,2],
[3,5]]

题解

昨天下午纠结我一下下午,晚上才照着人家的题解敲出来,今天上午又干坐着想了两个小时,才弄明白这个问题。话不多说,先上代码。第一次看到题目直接懵逼,以为是到数学题。观察了半天样例,可能是一道贪心。
具体怎么贪呢,由于我的方法耗时太长,所以可能没贪明白,不过既然题过了,还是分享一下思路。

方法一:贪心策略
python代码
def restoreMatrix(rowSum, colSum):
    matrix = [[0] * len(colSum) for _ in rowSum]
    for i in range(len(rowSum)):
        for j in range(len(colSum)):
            if rowSum[i]>colSum[j]:
                matrix[i][j]=colSum[j]
                colSum[j]=0
                rowSum[i]=rowSum[i]-matrix[i][j]
            else:
                matrix[i][j]=rowSum[i]
                rowSum[i]=0
                colSum[i]=rowSum[i]-matrix[i][j]
            matrix[i][j]+=1

    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            flag = True
            if (matrix[i][j] > 20):
                for m in range(len(matrix)):
                    if flag == False:
                        break
                    for n in range(len(matrix[i])):
                        if flag==False:
                            break
                        if m!=i or n!=j:
                            while (flag==True and matrix[m][n]>1 and matrix[m][j] < 20 and matrix[i][n] < 20):
                                matrix[m][n] -= 1
                                matrix[i][j] -= 1
                                matrix[m][j] += 1
                                matrix[i][n] += 1
                                if (matrix[i][j] <= 20):
                                    flag = False
                                    
    return matrix

C++代码
#include <iostream>   
#include <stdio.h>
using namespace std;

int main()
{
	int row_num[101], column_num[101];
	int i,j,p,q,num,item;
	int row[101][21] = {0}; //行
	int column[101][21] = {0};  //列
	int matrix[101][21][21] = {0};
	cin >> num; //num 矩阵数
	for (item = 1; item <= num; item++)
	{
		cin >> row_num[item] >> column_num[item];
		for (i = 1; i <= row_num[item]; i++)
		{
			cin >> row[item][i];
		}
		for (j = 1; j <= column_num[item]; j++)
		{
			cin >> column[item][j];
		}
		// 得到每一行每一列之和
		for (i = row_num[item]; i > 1; i--)
		{
			row[item][i] = row[item][i] - row[item][i - 1];
		}
		for (j = column_num[item]; j > 1; j--)
		{
			column[item][j] = column[item][j] - column[item][j - 1];
		}
		for (i = 1; i <= row_num[item]; i++)
		{
			row[item][i] = row[item][i] - column_num[item];
		}
		for (j = 1; j <= column_num[item]; j++)
		{
			column[item][j] = column[item][j] - row_num[item];
		}
	}
	
	for (item = 1; item <= num; item++) //遍历每个矩阵
	{
		for (i = 1; i <= row_num[item]; i++)  //行之和 row_num[item]行数
		{ 
			for (j = 1; j <= column_num[item]; j++)//列之和  column_num[temp列数
			{
				if (row[item][i] > column[item][j])
				{
						matrix[item][i][j] = column[item][j];
						column[item][j] = 0;
						row[item][i] = row[item][i] - matrix[item][i][j];
						if ( i>0){
							int l=0;
							l +=1;
						}
				}
				else
				{
						matrix[item][i][j] = row[item][i];
						row[item][i] = 0;
						column[item][j] = column[item][j] - matrix[item][i][j];
						if ( j>0){
							int l=0;
							l +=1;
						}
				}
				int k=20;
				int x=1;
				for (int v=0;v<k;v++)
				{
					if ( v>0)
						x+=1;
				}
				matrix[item][i][j] = matrix[item][i][j] + 1;
			}
		}
		bool Flag;
		for (i = 1; i <= row_num[item]; i++)
		{
			for (j = 1; j <= column_num[item]; j++)
			{
				Flag = true;
				if (matrix[item][i][j] > 20)
				{
					for (p = 1; p <= row_num[item] && Flag == true; p++)
					{
						for (q = 1; q <= column_num[item] && Flag == true; q++)
						{
							if (p != i || q != j)
							{
								while(Flag == true && matrix[item][p][q] > 1 && matrix[item][p][j] < 20 && matrix[item][i][q] < 20)
								{
									matrix[item][p][q] -= 1;
									
									matrix[item][i][j] -= 1;
									matrix[item][p][j] += 1;
									matrix[item][i][q] += 1;
									
									if (matrix[item][i][j] <= 20)
									{
										Flag = false;
									}
									int k=20;
									int x=1;
									for (int v=0;v<k;v++)
									{
										if ( v>0)
											x+=1;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	for (item = 1; item <= num; item++)
	{
		cout << "Matrix " << item << endl;
		for (i = 1; i <= row_num[item]; i++)
		{
			for (j = 1; j <= column_num[item]; j++)
			{
				cout << matrix[item][i][j];
				if (j < column_num[item])
				{
					cout << " ";
				}
				else
				{
					cout << endl;
				}
			}
		}
		
		if (item < num)
		{
			cout << endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值