Leetocde 1074 Number of Submatrices That Sum to Target (动态规划) (滑动窗口)

Leetocde 1074

问题描述

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 1:
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.

Note

  1. 1 <= matrix.length <= 300
  2. 1 <= matrix[0].length <= 300
  3. -1000 <= matrix[i] <= 1000
  4. -10^8 <= target <= 10^8

方法一

** Solution Java **
** 1070ms, 34.58% **
** 45.9MB, 100.00% **
class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int res = 0, m = matrix.length, n = matrix[0].length;
        for (int i = 0; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                matrix[i][j] += matrix[i][j - 1];
            }
        }
        for (int i = 0; i < n; ++i) {
            for (int j = i; j < n; ++j) {
                Map<Integer, Integer> count = new HashMap<>();
                count.put(0, 1);
                int cur = 0;
                for (int k = 0; k < m; ++k) {
                    cur += matrix[k][j] - (i > 0? matrix[k][i-1] : 0);
                    res += count.getOrDefault(cur - target, 0);
                    count.put(cur, count.getOrDefault(cur, 0) + 1);
                }
            }
        }
        return res;
    }
}
** Solution Python3 **
** 7500ms, beats 32.94% **
** 19.8MB, beats 100.00% **
class Solution:
    def numSubmatrixSumTarget(self, A, target):
        m, n = len(A), len(A[0])
        for row in A:
            for i in range(n - 1):
                row[i + 1] += row[i]
        res = 0
        for i in range(n):
            for j in range(i, n):
                c = collections.defaultdict(int)
                cur, c[0] = 0, 1
                for k in range(m):
                    cur += A[k][j] - (A[k][i - 1] if i > 0 else 0)
                    res += c[cur - target]
                    c[cur] += 1
        return res

方法二

** Solution Java **
** 850ms, beats 81.16% **
** 48.7MB, beats 100.00% **
class Solution{
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int[] temp = new int[m];
        int ans = 0;
        for (int left = 0; left < n; ++left) {
            Arrays.fill(temp, 0);
            for (int right = left; right < n; ++right) {
                for (int i = 0; i < m; ++i) 
                    temp[i] += matrix[i][right];
                ans += subCount(temp, target);
            }
        }
        return ans;
    }
    private int subCount(int[] temp, int target) {
        Map<Integer, Integer> preSum = new HashMap<>();
        int res = 0, curSum = 0;
        for (int t : temp) {
            curSum += t;
            if (curSum == target)
                ++res;
            if (preSum.containsKey(curSum - target)) 
                res += preSum.get(curSum - target);
            preSum.merge(curSum, 1, (a, b) -> a + b);
        }
        return res;
    }
}
posted @ 2020-03-06 22:28  willwuss  阅读(154)  评论(0编辑  收藏  举报