{x}
blog image

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][j] <= 1000
  • -10^8 <= target <= 10^8

Solution Explanation

This problem asks to find the number of submatrices within a given matrix whose elements sum up to a specified target value. The solution uses a prefix sum approach combined with a hashmap (or dictionary) to efficiently count the submatrices.

Algorithm:

  1. Iterate through all possible submatrices: The outer loop iterates through all possible top rows of submatrices (from index i to m-1, where m is the number of rows). The inner loop iterates from the current top row to the bottom row, effectively generating all submatrices starting from row i.

  2. Calculate column sums: For each submatrix, we calculate the sum of each column. This is done by accumulating the values in the corresponding columns of the original matrix. This step transforms the 2D submatrix problem into multiple 1D subarray sum problems (one for each column).

  3. 1D Subarray Sum Counting (f function): The f function efficiently counts the number of subarrays within a single array whose elements sum to the target. It utilizes a hashmap (d in the code) to store the cumulative sum and its frequency. For each element, it checks if a subarray ending at this element can achieve the target sum ( d[s - target]). If it exists, it means we found a subarray with the desired sum, so we increment the count.

  4. Aggregate Results: The main loop iterates through all submatrices and accumulates the counts returned by the f function for each column. This final count represents the total number of submatrices that sum to the target.

Time Complexity Analysis:

  • The outer loops iterate through all possible starting rows (O(m^2)).
  • The inner loops iterate through columns (O(n)).
  • The f function iterates through each column once (O(n)).
  • Therefore, the overall time complexity is O(m^2 * n^2).

Space Complexity Analysis:

  • The space complexity is dominated by the hashmap used in the f function, which can store up to n entries in the worst case.
  • Therefore, the space complexity is O(n).

Code Examples (Python):

from collections import defaultdict
 
class Solution:
    def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int:
        def f(nums: List[int]) -> int: # Helper function to count subarrays summing to target
            d = defaultdict(int)
            d[0] = 1
            cnt = s = 0
            for x in nums:
                s += x
                cnt += d[s - target] #Check if a subarray sum to target exists
                d[s] += 1
            return cnt
 
        m, n = len(matrix), len(matrix[0])
        ans = 0
        for i in range(m): # Iterate through all possible top rows
            col = [0] * n # Column sums for the current submatrix
            for j in range(i, m): # Iterate through all possible bottom rows
                for k in range(n): # calculate column sum
                    col[k] += matrix[j][k]
                ans += f(col) # Count subarrays in each column that sum to target
        return ans
 

The other languages (Java, C++, Go, TypeScript) follow a very similar structure, with only syntax differences reflecting the specific language's features. The core logic remains the same.