1074. Number of Submatrices That Sum to Target

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.

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

Rust Solution

struct Solution;
use std::collections::HashMap;

impl Solution {
    fn num_submatrix_sum_target(matrix: Vec<Vec<i32>>, target: i32) -> i32 {
        let n = matrix.len();
        let m = matrix[0].len();
        let mut prefix = vec![vec![]; n];
        for i in 0..n {
            let mut prev = 0;
            for j in 0..m {
                prev += matrix[i][j];
                prefix[i].push(prev);
            }
        }
        let mut res = 0;
        for j1 in 0..m {
            for j2 in j1..m {
                let mut hm: HashMap<i32, usize> = HashMap::new();
                hm.insert(0, 1);
                let mut sum = 0;
                for i in 0..n {
                    let cur = if j1 == 0 {
                        prefix[i][j2]
                    } else {
                        prefix[i][j2] - prefix[i][j1 - 1]
                    };
                    sum += cur;
                    res += *hm.entry(sum - target).or_default();
                    *hm.entry(sum).or_default() += 1;
                }
            }
        }
        res as i32
    }
}

#[test]
fn test() {
    let matrix = vec_vec_i32![[0, 1, 0], [1, 1, 1], [0, 1, 0]];
    let target = 0;
    let res = 4;
    assert_eq!(Solution::num_submatrix_sum_target(matrix, target), res);
    let matrix = vec_vec_i32![[1, -1], [-1, 1]];
    let target = 0;
    let res = 5;
    assert_eq!(Solution::num_submatrix_sum_target(matrix, target), res);

    let matrix = vec_vec_i32![
        [0, 1, 1, 1, 0, 1],
        [0, 0, 0, 0, 0, 1],
        [0, 0, 1, 0, 0, 1],
        [1, 1, 0, 1, 1, 0],
        [1, 0, 0, 1, 0, 0]
    ];
    let target = 0;

    let res = 43;
    assert_eq!(Solution::num_submatrix_sum_target(matrix, target), res);
}

Having problems with this solution? Click here to submit an issue on github.