leetcode 1253. Reconstruct a 2-Row Binary Matrix 解法 python3

本文介绍了一种算法,用于根据给定的行和列求和条件重构一个二行矩阵。通过贪心策略,确保满足所有条件,若无法满足则返回空数组。文章详细解释了解题思路,并提供了两种实现方式的代码示例。

一.问题描述

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 0 or 1.
  • 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], where colsum is given as an integer array with length n.

Your task is to reconstruct the matrix with upperlower 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^5
  • 0 <= upper, lower <= colsum.length
  • 0 <= 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
        

2.一遍迭代,来自:https://leetcode.com/problems/reconstruct-a-2-row-binary-matrix/discuss/425383/Python-clearest-O(n)-greedy

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 []

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值