LeetCode #1074 Number of Submatr

2022-03-25  本文已影响0人  air_melt

1074 Number of Submatrices That Sum to Target 元素和为目标值的子矩阵数量

Description:
Given a matrix and a target, return the number of non-empty submatrices that sum to target.

A submatrix x1, y1, x2, y2 is the set of all cells matrix[x][y] with x1 <= x <= x2 and y1 <= y <= y2.

Two submatrices (x1, y1, x2, y2) and (x1', y1', x2', y2') are different if they have some coordinate that is different: for example, if x1 != x1'.

Example:

Example 1:

matrix

Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
Output: 4
Explanation: The four 1x1 submatrices that only contain 0.

Example 2:

Input: matrix = [[1,-1],[-1,1]], target = 0
Output: 5
Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.

Example 3:

Input: matrix = [[904]], target = 0
Output: 0

Constraints:

1 <= matrix.length <= 100
1 <= matrix[0].length <= 100
-1000 <= matrix[i] <= 1000
-10^8 <= target <= 10^8

题目描述:
给出矩阵 matrix 和目标值 target,返回元素总和等于目标值的非空子矩阵的数量。

子矩阵 x1, y1, x2, y2 是满足 x1 <= x <= x2 且 y1 <= y <= y2 的所有单元 matrix[x][y] 的集合。

如果 (x1, y1, x2, y2) 和 (x1', y1', x2', y2') 两个子矩阵中部分坐标不同(如:x1 != x1'),那么这两个子矩阵也不同。

示例 :

示例 1:

矩阵

输入:matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
输出:4
解释:四个只含 0 的 1x1 子矩阵。

示例 2:

输入:matrix = [[1,-1],[-1,1]], target = 0
输出:5
解释:两个 1x2 子矩阵,加上两个 2x1 子矩阵,再加上一个 2x2 子矩阵。

示例 3:

输入:matrix = [[904]], target = 0
输出:0

提示:

1 <= matrix.length <= 100
1 <= matrix[0].length <= 100
-1000 <= matrix[i] <= 1000
-10^8 <= target <= 10^8

思路:

  1. 前缀和
    预处理二维数组前缀和
    pre[i + 1][j + 1] = pre[i][j + 1] + pre[i + 1][j] - pre[i][j] + matrix[i][j]
    那么任意一个区间[k, l], [i, j]的前缀和可由
    pre[i][j] - pre[i][l - 1] - pre[k - 1][j] + pre[k - 1][l - 1]
    得到, 其中[k, l] 表示矩形的左上角的点的坐标, [i, j] 表示矩形的右下角的点的坐标
    时间复杂度O(m ^ 2 * n ^ 2), 空间复杂度O(mn)
  2. 前缀和 ➕ 哈希
    预处理二维数组前缀和
    固定上下边界和右边界
    整个上下边界为 cur = pre[buttom][right] - pre[top - 1][right], 如果等于 target, 结果加 1
    否则在哈希表中查找 cur - target, 结果加上该值
    哈希表存入 cur, 表示前缀和出现的次数
    时间复杂度O(mn ^ 2), 空间复杂度O(mn)

代码:
C++:

class Solution 
{
public:
    int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) 
    {
        int m = matrix.size(), n = matrix.front().size(), result = 0;
        vector<vector<int>> pre(m + 1, vector<int>(n + 1));
        for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) pre[i + 1][j + 1] = pre[i][j + 1] + pre[i + 1][j] - pre[i][j] + matrix[i][j];
        for (int i = 1; i <= m; i++)
        {
            for (int j = i; j <= m; j++)
            {
                int cur = 0;
                unordered_map<int, int> m;
                for (int k = 1; k <= n; k++)
                {
                    cur = pre[j][k] - pre[i - 1][k];
                    result += (cur == target) + m[cur - target];
                    ++m[cur];
                }
            }
        }
        return result;
    }
};

Java:

class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length, result = 0, pre[][] = new int[m + 1][n + 1];
        for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) pre[i + 1][j + 1] = pre[i][j + 1] + pre[i + 1][j] - pre[i][j] + matrix[i][j];
        for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= i; k++) for (int l = 1; l <= j; l++) result += (pre[i][j] - pre[i][l - 1] - pre[k - 1][j] + pre[k - 1][l - 1] == target ? 1 : 0);
        return result;
    }
}

Python:

class Solution:
    def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int:
        m, n, pre, result = len(matrix), len(matrix[0]), [list(accumulate(i)) for i in matrix], 0
        for i in range(1, m):
            for j in range(n):
                pre[i][j] += pre[i - 1][j]
        for top in range(m):
            for buttom in range(top, m):
                d = defaultdict(int)
                for right in range(n):
                    result += ((cur := pre[buttom][right] - (pre[top - 1][right] if top else 0)) == target) + d[cur - target]
                    d[cur] += 1
        return result
上一篇 下一篇

猜你喜欢

热点阅读