一.问题描述
Given the following details of a matrix with n columns and 2 rows :
- The matrix is a binary matrix, which means each element in the matrix can be
0or1. - The sum of elements of the 0-th(upper) row is given as
upper. - The sum of elements of the 1-st(lower) row is given as
lower. - The sum of elements in the i-th column(0-indexed) is
colsum[i], wherecolsumis given as an integer array with lengthn.
Your task is to reconstruct the matrix with upper, lower and colsum.
Return it as a 2-D integer array.
If there are more than one valid solution, any of them will be accepted.
If no valid solution exists, return an empty 2-D array.
Example 1:
Input: upper = 2, lower = 1, colsum = [1,1,1]
Output: [[1,1,0],[0,0,1]]
Explanation: [[1,0,1],[0,1,0]], and [[0,1,1],[1,0,0]] are also correct answers.
Example 2:
Input: upper = 2, lower = 3, colsum = [2,2,1,1]
Output: []
Example 3:
Input: upper = 5, lower = 5, colsum = [2,1,2,0,1,0,1,2,0,1]
Output: [[1,1,1,0,1,0,0,1,0,0],[1,0,1,0,0,0,1,1,0,1]]
Constraints:
1 <= colsum.length <= 10^50 <= upper, lower <= colsum.length0 <= colsum[i] <= 2
二.解题思路
题目大概是说一个数组有2行,n列。
要求是:第一行和是m,第二行和是n,每一列也有和的要求是colsum。
要求返回一个数组满足上述要求的数组,如果没有满足的数组就返回空数组。
判断这个要求是否能满足:
1.m+n==sum(colsum),如果这条不能满足,直接out
2.就是m+n==sum(colsum)了,但是由于colsum的要求和每行和的冲突导致失败。
为什么colsum要求会和每行和冲突?是因为某行的某列要求为1,但是却满足不了,该行的值不够用了。
再考虑以下啥时候会必须要求某行某列为1? 当colsum[i]为2的时候。
即对于colsum中所有和为2,必须两行都是1,这是首先需要满足的,但就会导致upper或者lower不够用,虽然upper+lower==colsum。
至于具体的两行值的分配,最简单的用贪心算法。
首先像我们说的,先满足所有colsum[i]为2的列,因为这种你没得分配,必须满足。
在这一步如果发现upper或者lower不够用,说明失败,返回空。
剩下就是满足所有colsum[i]为1的,相当于做试卷,n道双选题,只能选A或者B,随便你怎么选,但是不能空着。
贪心法就是,对每个colsum[i]为1的,把剩余的upper全用掉,全分到第一层(或者第二层,随你喜好)。
upper用完之后,再用剩下的lower把剩余的colsum[i]为1的弄完。
时间复杂度:O(N) 空间复杂度:O(N)
更新:
上述方法需要两次遍历,第一次遍历满足所有colsum[i]是2的列。
其实还有只用一次遍历的方法,我们2次遍历是因为第一次遍历来找是不是能满足要求。
不能同时处理的原因是可能把colsum[i]为1的分配给了某行导致后面colsum[i]为2的不够用了。
但是想一下,假如当前处理到第i列,对于i+1~end列,假设有t个colsum[i]为2的列,upper和lower中较小的那个大于t就行了。
因此我们每次分配colsum[i]为1的列的时候,把upper或者lower中较大的那个分配出去,这样子并不影响后面碰到colsum[i]为2的分配。因为能否满足后面所有的colsum[i]为2的列取决于upper和lower中较小那个。
当然这个得到最后才能判断是否满足要求,因此两个方法到底哪个快得看数据的分布了。如果数据中大部分都是不满足的,那么方法1应该更快,如果大部分都是满足条件的,那应该是2快。
就leetcode的数据来说,方法一快一点。
更多leetcode算法题解法: 专栏 leetcode算法从零到结束
三.源码
class Solution:
def reconstructMatrix(self, upper: int, lower: int, colsum: List[int]) -> List[List[int]]:
if upper+lower != sum(colsum):return []
n,start=len(colsum),0
res=[[0]*n for i in range(2)]
for i in range(n):
if colsum[i]==2:
res[0][i],res[1][i]=1,1
upper-=1
lower-=1
if upper<0 or lower <0: return []
for j in range(n):
if colsum[j]==1:
if upper:
res[0][j]=1
upper-=1
else:
res[1][j]=1
lower-=1
return res
class Solution:
def reconstructMatrix(self, upper: int, lower: int, colsum: List[int]) -> List[List[int]]:
res = [[0]*len(colsum) for _ in range(2)]
for i in range(len(colsum)):
if colsum[i] == 2:
res[0][i] += 1
res[1][i] += 1
upper -= 1
lower -= 1
elif colsum[i]:
if upper > lower:
res[0][i] += 1
upper -= 1
else:
res[1][i] += 1
lower -= 1
return res if not (upper or lower) else []
本文介绍了一种算法,用于根据给定的行和列求和条件重构一个二行矩阵。通过贪心策略,确保满足所有条件,若无法满足则返回空数组。文章详细解释了解题思路,并提供了两种实现方式的代码示例。
147

被折叠的 条评论
为什么被折叠?



