Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions problems/2906-construct-product-matrix/analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 2906. Construct Product Matrix

[LeetCode Link](https://leetcode.com/problems/construct-product-matrix/)

Difficulty: Medium
Topics: Array, Matrix, Prefix Sum
Acceptance Rate: 37.8%

## Hints

### Hint 1

This problem is very similar to the classic "Product of Array Except Self" problem. Think about how you would solve that 1D problem, then consider how to adapt it to a 2D matrix.

### Hint 2

You can flatten the 2D matrix into a 1D sequence and apply a prefix/suffix product technique. For each position, the answer is the product of everything before it multiplied by the product of everything after it — all taken modulo 12345.

### Hint 3

The critical insight is that you only need two passes over the flattened array: one forward pass to build prefix products and one backward pass to build suffix products. At each position, multiply the prefix product (of all elements before it) by the suffix product (of all elements after it), modulo 12345. This avoids computing the total product and dividing (which wouldn't work well with modular arithmetic anyway).

## Approach

1. **Flatten the matrix conceptually**: Treat the `n x m` grid as a 1D array of length `n * m` by iterating row by row.

2. **Forward pass (prefix products)**: Traverse the flattened array left to right. Maintain a running product. Before updating the running product with the current element, store the running product as the prefix value for the current position. This gives, for each cell, the product of all elements that come before it (in row-major order), modulo 12345.

3. **Backward pass (suffix products)**: Traverse right to left. Maintain a running product. For each position, multiply the already-stored prefix value by the current suffix running product. Then update the suffix running product with the current grid element.

4. **Result**: After both passes, each cell in the result matrix contains `(product of all other elements) % 12345`.

This is essentially the same algorithm as "Product of Array Except Self" (LC 238), extended to a 2D grid and with modular arithmetic.

## Complexity Analysis

Time Complexity: O(n * m) — two linear passes over all elements.
Space Complexity: O(1) extra beyond the output matrix — prefix and suffix products are computed using a single running variable each, and the result is stored in-place in the output matrix.

## Edge Cases

- **Element equals 12345 (or a multiple)**: That element is 0 mod 12345, which means every other cell's product includes a zero factor. The prefix/suffix approach handles this naturally.
- **Multiple multiples of 12345**: If two or more elements are 0 mod 12345, then every cell's product will be 0 (since every cell excludes at most one zero, but at least one zero remains).
- **Single row or single column matrix**: The algorithm works the same since we treat the matrix as a flat array.
- **Minimum size (n * m = 2)**: Each cell is simply the other cell's value mod 12345.
- **Large values**: Individual grid values can be up to 10^9, so intermediate products must use modular arithmetic at every step to avoid overflow.
59 changes: 59 additions & 0 deletions problems/2906-construct-product-matrix/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
number: "2906"
frontend_id: "2906"
title: "Construct Product Matrix"
slug: "construct-product-matrix"
difficulty: "Medium"
topics:
- "Array"
- "Matrix"
- "Prefix Sum"
acceptance_rate: 3777.4
is_premium: false
created_at: "2026-03-24T03:18:07.776456+00:00"
fetched_at: "2026-03-24T03:18:07.776456+00:00"
link: "https://leetcode.com/problems/construct-product-matrix/"
date: "2026-03-24"
---

# 2906. Construct Product Matrix

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:

* Each element `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 <= 105`
* `1 <= m == grid[i].length <= 105`
* `2 <= n * m <= 105`
* `1 <= grid[i][j] <= 109`
36 changes: 36 additions & 0 deletions problems/2906-construct-product-matrix/solution_daily_20260324.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

// Construct Product Matrix using prefix and suffix products modulo 12345.
// Flatten the 2D grid conceptually. Forward pass stores prefix products,
// backward pass multiplies in suffix products. O(n*m) time, O(1) extra space.
func constructProductMatrix(grid [][]int) [][]int {
const mod = 12345
n := len(grid)
m := len(grid[0])

// Initialize result matrix
p := make([][]int, n)
for i := range p {
p[i] = make([]int, m)
}

// Forward pass: store prefix products
prefix := 1
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
p[i][j] = prefix
prefix = prefix * (grid[i][j] % mod) % mod
}
}

// Backward pass: multiply by suffix products
suffix := 1
for i := n - 1; i >= 0; i-- {
for j := m - 1; j >= 0; j-- {
p[i][j] = p[i][j] * suffix % mod
suffix = suffix * (grid[i][j] % mod) % mod
}
}

return p
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"reflect"
"testing"
)

func TestConstructProductMatrix(t *testing.T) {
tests := []struct {
name string
grid [][]int
expected [][]int
}{
{
name: "example 1: 2x2 grid",
grid: [][]int{{1, 2}, {3, 4}},
expected: [][]int{{24, 12}, {8, 6}},
},
{
name: "example 2: single column with 12345",
grid: [][]int{{12345}, {2}, {1}},
expected: [][]int{{2}, {0}, {0}},
},
{
name: "edge case: minimum size grid (2 elements)",
grid: [][]int{{5, 7}},
expected: [][]int{{7, 5}},
},
{
name: "edge case: all elements are 1",
grid: [][]int{{1, 1, 1}, {1, 1, 1}},
expected: [][]int{{1, 1, 1}, {1, 1, 1}},
},
{
name: "edge case: multiple multiples of 12345",
grid: [][]int{{12345, 12345}, {2, 3}},
expected: [][]int{{0, 0}, {0, 0}},
},
{
name: "edge case: large values",
grid: [][]int{{1000000000, 1000000000}},
expected: [][]int{{5620, 5620}},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := constructProductMatrix(tt.grid)
if !reflect.DeepEqual(result, tt.expected) {
t.Errorf("got %v, want %v", result, tt.expected)
}
})
}
}