Given a 2D matrix matrix
, handle multiple queries of the following type:
matrix
inside the rectangle defined by its upper left corner (row1, col1)
and lower right corner (row2, col2)
.Implement the NumMatrix
class:
NumMatrix(int[][] matrix)
Initializes the object with the integer matrix matrix
.int sumRegion(int row1, int col1, int row2, int col2)
Returns the sum of the elements of matrix
inside the rectangle defined by its upper left corner (row1, col1)
and lower right corner (row2, col2)
.You must design an algorithm where sumRegion
works on O(1)
time complexity.
Example 1:
Input ["NumMatrix", "sumRegion", "sumRegion", "sumRegion"] [[[[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]] Output [null, 8, 11, 12] Explanation NumMatrix numMatrix = new NumMatrix([[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]]); numMatrix.sumRegion(2, 1, 4, 3); // return 8 (i.e sum of the red rectangle) numMatrix.sumRegion(1, 1, 2, 2); // return 11 (i.e sum of the green rectangle) numMatrix.sumRegion(1, 2, 2, 4); // return 12 (i.e sum of the blue rectangle)
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 200
-104 <= matrix[i][j] <= 104
0 <= row1 <= row2 < m
0 <= col1 <= col2 < n
104
calls will be made to sumRegion
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding a sum within a rectangle in a grid involves directly calculating the sum for every possible rectangle specified by the user. We achieve this by simply looking at each cell within the given rectangle and adding its value to a running total.
Here's how the algorithm would work step-by-step:
class NumMatrix:
def __init__(self, matrix):
self.matrix = matrix
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
total_sum = 0
# Iterate through rows within the specified range
for row_index in range(row1, row2 + 1):
# Iterate through columns within the specified range
for column_index in range(col1, col2 + 1):
# Add the current cell's value to the total sum
total_sum += self.matrix[row_index][column_index]
return total_sum
# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# param_1 = obj.sumRegion(row1,col1,row2,col2)
We can solve this efficiently by pre-calculating sums of rectangles within the larger grid. By storing these pre-calculated sums, we can quickly determine the sum of any rectangular region using only a few simple calculations.
Here's how the algorithm would work step-by-step:
class NumMatrix:
def __init__(self, matrix):
self.matrix = matrix
if not matrix or not matrix[0]:
self.sum_grid = [[]]
return
number_of_rows = len(matrix)
number_of_cols = len(matrix[0])
self.sum_grid = [[0] * (number_of_cols + 1) for _ in range(number_of_rows + 1)]
# Build the sum grid for fast range queries
for row_index in range(number_of_rows):
for col_index in range(number_of_cols):
self.sum_grid[row_index + 1][col_index + 1] = self.sum_grid[row_index + 1][col_index] + self.sum_grid[row_index][col_index + 1] - self.sum_grid[row_index][col_index] + matrix[row_index][col_index]
def sumRegion(self, row1, col1, row2, col2):
# Using precomputed sums for O(1) query
return self.sum_grid[row2 + 1][col2 + 1] - self.sum_grid[row1][col2 + 1] - self.sum_grid[row2 + 1][col1] + self.sum_grid[row1][col1]
# Your NumMatrix object will be instantiated and called as such:
# numMatrix = NumMatrix(matrix)
# numMatrix.sumRegion(0, 1, 2, 3)
# numMatrix.sumRegion(1, 2, 3, 4)
Case | How to Handle |
---|---|
Null or empty matrix input | Return 0 or throw an exception indicating invalid input as there's no matrix to sum. |
Zero width or height matrix | Return 0 if the matrix has zero rows or zero columns, signifying an empty matrix. |
row1 > row2 or col1 > col2 | Return 0 because the specified region is invalid (top-left corner is below/to the right of the bottom-right corner). |
row1, col1, row2, or col2 are out of bounds of the matrix | Adjust the coordinates to be within bounds of the matrix or throw an exception indicating an invalid range. |
Large matrix dimensions (potential for integer overflow) | Use long data type to store prefix sums to avoid integer overflow during summation. |
Matrix with very large positive or negative values | Ensure that intermediate sums do not overflow even with large matrix elements, using long if necessary. |
Sum region covering the entire matrix | The prefix sum implementation should handle this case correctly, returning the total sum of all matrix elements. |
Multiple calls to sumRegion after preprocessing | The prefix sum data structure should allow for efficient calculation of the sum for any given region after initial construction. |