📜  二进制矩阵中给定维度的子矩阵中存在的最小 1 数(1)

📅  最后修改于: 2023-12-03 14:49:02.454000             🧑  作者: Mango

二进制矩阵中给定维度的子矩阵中存在的最小 1 数

问题描述

给定一个 $m\times n$ 的二进制矩阵,以及两个整数 $k_1,k_2$,求所有大小为 $k_1\times k_2$ 的子矩阵中,1 的最小个数。

解决思路

首先,我们需要一个辅助矩阵 $sum$,用于记录左上角顶点为 $(i,j)$,大小为 $k_1\times k_2$ 的子矩阵中 1 的个数。显然,这个矩阵可以用动态规划的思想来求解:

$$ sum_{i,j}=sum_{i-1,j}+sum_{i,j-1}-sum_{i-1,j-1}+matrix_{i,j} $$

其中,$matrix_{i,j}$ 表示原始矩阵中第 $i$ 行第 $j$ 列的元素值。

有了辅助矩阵 $sum$,我们只需要遍历所有的 $k_1\times k_2$ 的子矩阵,分别计算它们中 1 的个数,并得到最小值即可。具体实现可以参考下面的代码:

def min_ones(matrix, k1, k2):
    m, n = len(matrix), len(matrix[0])
    sum = [[0] * n for _ in range(m)]
    for i in range(k1):
        for j in range(k2):
            sum[0][0] += matrix[i][j]
    for i in range(1, m - k1 + 1):
        sum[i][0] = sum[i - 1][0]
        for j in range(k2):
            sum[i][0] += matrix[i + k1 - 1][j] - matrix[i - 1][j]
    for i in range(k1):
        for j in range(1, n - k2 + 1):
            sum[0][j] = sum[0][j - 1]
            for k in range(k1):
                sum[0][j] += matrix[k][j + k2 - 1] - matrix[k][j - 1]
    for i in range(1, m - k1 + 1):
        for j in range(1, n - k2 + 1):
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + \
                        matrix[i + k1 - 1][j + k2 - 1] - matrix[i - 1][j + k2 - 1] - \
                        matrix[i + k1 - 1][j - 1] + matrix[i - 1][j - 1]
    ans = 1e9
    for i in range(m - k1 + 1):
        for j in range(n - k2 + 1):
            cnt = sum[i + k1 - 1][j + k2 - 1]
            if i > 0: cnt -= sum[i - 1][j + k2 - 1]
            if j > 0: cnt -= sum[i + k1 - 1][j - 1]
            if i > 0 and j > 0: cnt += sum[i - 1][j - 1]
            ans = min(ans, k1 * k2 - cnt)
    return ans
复杂度分析

代码中有两个嵌套的循环,分别遍历了所有的 $k_1\times k_2$ 的子矩阵,所以时间复杂度为 $O(mnk_1k_2)$,其中 $m,n$ 分别为原始矩阵的行数和列数。

总结

本题可以用动态规划的思想来求解。具体来说,我们需要用一个辅助矩阵来记录左上角顶点为 $(i,j)$,大小为 $k_1\times k_2$ 的子矩阵中 1 的个数。然后,遍历所有的 $k_1\times k_2$ 的子矩阵,分别计算它们中 1 的个数,并得到最小值即可。时间复杂度为 $O(mnk_1k_2)$。