Range Sum Query 2D Immutable

To solve this coding challenge, we need to create a class that can efficiently compute the sum of elements within a submatrix of a given 2D matrix. Here's a detailed methodology and pseudocode to accomplish this task.

Explanation

To achieve a solution where the sumRegion function works in O(1) time complexity, we can use a preprocessing step where we build a
dp
table (dynamic programming table) that holds the cumulative sums of submatrices. This preprocessing takes O(m * n) time, but querying any submatrix sum will be done in constant time.
Here's the detailed thought process and explanation:
  1. Initialization :
    • When initializing the
      NumMatrix
      object, we need to preprocess the matrix to set up our
      dp
      table. This table will store at each position
      (i, j)
      the sum of elements in the submatrix from the top-left corner
      (0, 0)
      to the position
      (i, j)
      .
  2. Filling the
    dp
    Table
    :
    • We iterate over each element in the original matrix and use the values from neighboring cells in
      dp
      to compute the cumulative sum at each cell
      (i, j)
      .
    • The value at
      dp[i][j]
      is computed using the formula:
      • \[ \text{dp}[i][j] = \text{matrix}[i-1][j-1] + \text{dp}[i-1][j] + \text{dp}[i][j-1] - \text{dp}[i-1][j-1] \]
    • This formula ensures that we add the current element and also account for the sums of submatrices ending at
      (i-1, j)
      ,
      (i, j-1)
      and subtracts the overlapping submatrix ending at
      (i-1, j-1)
      .
  3. Querying Submatrix Sum :
    • To get the sum of elements in the submatrix specified by corners
      (row1, col1)
      to
      (row2, col2)
      , we use the precomputed cumulative sums from
      dp
      .
    • The sum can be calculated as:
      • \[ \text{sumRegion} = \text{dp}[row2+1][col2+1] - \text{dp}[row1][col2+1] - \text{dp}[row2+1][col1] + \text{dp}[row1][col1] \]
    • This formula subtracts the unnecessary outer regions and adds back the overlapping submatrix to get the correct sum.

Detailed Steps in Pseudocode

Initializing the NumMatrix class

                                            
class NumMatrix:
    # Initialization of NumMatrix with the given matrix
    function __init__(matrix):
        if matrix is empty:
            return  # Early exit if the matrix is empty
        
        num_rows = number of rows in matrix
        num_columns = number of columns in matrix
        
        # Initialize the dp table with an extra row and column with zeros
        dp = 2D array of size (num_rows + 1) x (num_columns + 1) filled with zeros
        
        # Fill the dp table with cumulative sums
        for i from 1 to num_rows:
            for j from 1 to num_columns:
                dp[i][j] = matrix[i-1][j-1] + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1]

                                        

Summing the Region

                                            
    # Function to get the sum of the specified submatrix
    function sumRegion(row1, col1, row2, col2):
        # Compute the sum of the submatrix using the dp table
        return dp[row2+1][col2+1] - dp[row2+1][col1] - dp[row1][col2+1] + dp[row1][col1]

                                        
Explanation:
  • First, we add the sum of the submatrix ending at
    (row2, col2)
    which is
    dp[row2+1][col2+1]
    .
  • Then, we subtract the areas that extend beyond
    (row1, col1)
    by subtracting the sums ending at
    (row2, col1-1)
    and
    (row1-1, col2)
    .
  • Finally, we add back the area which extends beyond both boundaries twice, once for each, which is why we add back the sum ending at
    (row1-1, col1-1)
    .
By initializing our
dp
table during the object construction, we ensure that each query to sumRegion is handled in constant time, thus meeting the requirements of the challenge efficiently.