leetcode
leetcode 1151 ~ 1200
重构 2 行二进制矩阵

重构 2 行二进制矩阵

难度:

标签:

题目描述

代码结果

运行时间: 57 ms, 内存: 21.6 MB


/*
 * 思路:
 * 我们使用 Java Stream 构建解法。
 * 使用 List<List<Integer>> 来表示矩阵,并使用流来遍历 colsum 数组。
 */

import java.util.*;
import java.util.stream.*;

public class SolutionStream {
    public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colsum) {
        int n = colsum.length;
        int[] upperRow = new int[n];
        int[] lowerRow = new int[n];

        for (int i = 0; i < n; i++) {
            if (colsum[i] == 2) {
                upperRow[i] = 1;
                lowerRow[i] = 1;
                upper--;
                lower--;
            } else if (colsum[i] == 1) {
                if (upper > lower) {
                    upperRow[i] = 1;
                    upper--;
                } else {
                    lowerRow[i] = 1;
                    lower--;
                }
            }
        }

        if (upper != 0 || lower != 0) {
            return new ArrayList<>(); // 返回空数组表示无法构建
        }

        List<List<Integer>> result = Arrays.asList(
            Arrays.stream(upperRow).boxed().collect(Collectors.toList()),
            Arrays.stream(lowerRow).boxed().collect(Collectors.toList())
        );

        return result;
    }
}

解释

方法:

该题解的思路基于有效地分配'1'到两行上,以满足每列的和(colsum)以及每行的和(upper和lower)。首先,如果colsum的总和不等于upper和lower的和,那么无法构建所需的矩阵,因此直接返回空数组。接着检查colsum中值为2的个数是否超过upper和lower中的最小值,如果超过,则同样返回空数组,因为无法满足列和的要求。然后,初始化两个数组up和low,分别表示最终矩阵的第一行和第二行。先遍历colsum,将所有值为2的情况分配到两行,因为colsum为2意味着这一列的两个位置必须都是1。接着,再次遍历colsum,针对值为1的情况,尽量分配到第一行(up),直到第一行的和达到upper。最后,根据colsum减去up的值来确定low的值。这样可以构建满足条件的矩阵。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,如果`colsum`数组中值为2的元素个数超过`upper`和`lower`中的最小值时,为什么直接返回空数组?
在题解中,如果`colsum`数组中值为2的元素个数超过`upper`和`lower`中的最小值,这意味着至少有一行无法容纳必须置为1的元素,因为每个值为2的`colsum`代表这一列的两行都必须是1。如果超过了任一行能承受的最大1的数量,就无法构造一个有效的解,因此返回空数组。
🦆
题解中提到,如果`colsum`的总和不等于`upper`加`lower`之和,就返回空数组。这是基于什么逻辑?
这是基于总数的匹配原则。`colsum`的总和代表整个矩阵中1的总数量。而`upper`和`lower`分别代表第一行和第二行应有的1的总数。如果`colsum`的总和不等于`upper`加`lower`之和,那么就不存在一种方式将1正确分配到两行使得每行的1的数量分别等于`upper`和`lower`,因此无法构建一个有效的矩阵,需要返回空数组。
🦆
在分配`colsum`值为1的元素时,为什么首选分配到第一行(up)而不是均匀分配到两行?
优先将`colsum`中的值为1的元素分配给第一行(`up`)的策略是尝试先满足一行的需求,以便更容易控制和平衡剩余元素的分配。这样做可以确保在满足第一行的需求后,剩余的1可以直接分配给第二行,从而简化逻辑和实现。如果均匀分配,则可能导致两行同时未达到所需的`upper`和`lower`值,处理起来更复杂。
🦆
如果在分配过程中第一行(up)的和已经达到了`upper`,但`colsum`中仍有值为1的元素未处理,这些元素是如何被分配的?
在这种情况下,所有剩余的`colsum`中值为1的元素必须分配给第二行(`low`)。这是因为第一行(`up`)的和已经达到了其限制`upper`,不能再添加更多的1。因此,剩余的1将全部分配到第二行,以确保整个矩阵的列和符合`colsum`的要求。

相关问题