Given a 0-indexed 2D integer matrix grid of size n * m, we define a 0-indexed 2D matrix p of size n * m as the product matrix of grid if the following condition is met:
p[i][j] is calculated as the product of all elements in grid except for the element grid[i][j]. This product is then taken modulo 12345.Return the product matrix of grid.
Example 1:
Input: grid = [[1,2],[3,4]] Output: [[24,12],[8,6]] Explanation: p[0][0] = grid[0][1] * grid[1][0] * grid[1][1] = 2 * 3 * 4 = 24 p[0][1] = grid[0][0] * grid[1][0] * grid[1][1] = 1 * 3 * 4 = 12 p[1][0] = grid[0][0] * grid[0][1] * grid[1][1] = 1 * 2 * 4 = 8 p[1][1] = grid[0][0] * grid[0][1] * grid[1][0] = 1 * 2 * 3 = 6 So the answer is [[24,12],[8,6]].
Example 2:
Input: grid = [[12345],[2],[1]] Output: [[2],[0],[0]] Explanation: p[0][0] = grid[0][1] * grid[0][2] = 2 * 1 = 2. p[0][1] = grid[0][0] * grid[0][2] = 12345 * 1 = 12345. 12345 % 12345 = 0. So p[0][1] = 0. p[0][2] = grid[0][0] * grid[0][1] = 12345 * 2 = 24690. 24690 % 12345 = 0. So p[0][2] = 0. So the answer is [[2],[0],[0]].
Constraints:
1 <= n == grid.length <= 1051 <= m == grid[i].length <= 1052 <= n * m <= 1051 <= grid[i][j] <= 109When 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:
To build the new grid of numbers, we calculate the value for each spot individually. For any given spot, the most direct method is to look at the original grid and multiply all of its numbers together, but deliberately skipping the number that was in the same spot we are currently trying to calculate.
Here's how the algorithm would work step-by-step:
def construct_product_matrix(grid):
number_of_rows = len(grid)
number_of_columns = len(grid[0])
modulus = 12345
# Create a new grid of the same size, initialized to zero, to store the results.
result_matrix = [[0] * number_of_columns for _ in range(number_of_rows)]
# We must iterate through each cell of the matrix we are trying to construct.
for target_row in range(number_of_rows):
for target_column in range(number_of_columns):
# Reset the product to 1 for each new cell because it is the multiplicative identity.
product_for_target_cell = 1
# For each target cell, scan the entire original grid to calculate the product of other elements.
for source_row in range(number_of_rows):
for source_column in range(number_of_columns):
if source_row == target_row and source_column == target_column:
continue
product_for_target_cell *= grid[source_row][source_column]
product_for_target_cell %= modulus
result_matrix[target_row][target_column] = product_for_target_cell
return result_matrixTo find the product of all numbers except one for each spot in a grid, we avoid repetitive work. The key is to make two sweeps across the grid: one from the beginning to end, calculating the product of numbers 'before' each spot, and another from end to beginning for numbers 'after' each spot. Combining these two results gives us the answer for each spot efficiently.
Here's how the algorithm would work step-by-step:
def construct_product_matrix(grid: list[list[int]]) -> list[list[int]]:
number_of_rows = len(grid)
number_of_columns = len(grid[0])
MODULO = 12345
product_matrix = [[1] * number_of_columns for _ in range(number_of_rows)]
# The first pass computes prefix products, storing the product of all elements before each cell.
prefix_product = 1
for row_index in range(number_of_rows):
for column_index in range(number_of_columns):
product_matrix[row_index][column_index] = prefix_product
prefix_product = (prefix_product * grid[row_index][column_index]) % MODULO
# The second pass computes suffix products and combines them with the stored prefix products.
suffix_product = 1
for row_index in range(number_of_rows - 1, -1, -1):
for column_index in range(number_of_columns - 1, -1, -1):
# The final value is the stored prefix product multiplied by the current suffix product.
product_matrix[row_index][column_index] = (product_matrix[row_index][column_index] * suffix_product) % MODULO
suffix_product = (suffix_product * grid[row_index][column_index]) % MODULO
return product_matrix| Case | How to Handle |
|---|---|
| Cumulative product overflow | Apply the modulo operation after each multiplication step to ensure the running product remains within a manageable range. |
| Overflow within a single multiplication step | Use a 64-bit integer type for calculations like (a * b) % m to prevent intermediate values from overflowing a 32-bit integer. |
| Grid elements being multiples of the modulus | These elements are correctly treated as 0 modulo 12345, causing any product that includes them to also become 0. |
| Grid elements sharing prime factors with the modulus | A prefix-suffix product approach avoids division, bypassing issues with non-existent modular multiplicative inverses for certain numbers. |
| Maximum grid size leading to Time Limit Exceeded | The solution must have a linear time complexity, O(n*m), to process up to 10^5 elements efficiently. |
| Minimum grid size (two elements) | The prefix-suffix logic must correctly handle the boundaries for the first and last elements, which have no preceding or succeeding elements respectively. |
| Highly skewed grid dimensions | Flattening the grid into a 1D array makes the algorithm robust and independent of the specific n and m values. |
| Inputs violating stated constraints | A production-ready solution should clarify how to handle invalid inputs like null or improperly sized grids, possibly by throwing an error. |