Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
Given the following details of a matrix with n columns and 2 rows :
0 or 1.upper.lower.colsum[i], where colsum is given as an integer array with length n.Your task is to reconstruct the matrix with upper, lower and colsum.
Return it as a 2-D integer array.
If there are more than one valid solution, any of them will be accepted.
If no valid solution exists, return an empty 2-D array.
Example 1:
Input: upper = 2, lower = 1, colsum = [1,1,1] Output: [[1,1,0],[0,0,1]] Explanation: [[1,0,1],[0,1,0]], and [[0,1,1],[1,0,0]] are also correct answers.
Example 2:
Input: upper = 2, lower = 3, colsum = [2,2,1,1] Output: []
Example 3:
Input: upper = 5, lower = 5, colsum = [2,1,2,0,1,0,1,2,0,1] Output: [[1,1,1,0,1,0,0,1,0,0],[1,0,1,0,0,0,1,1,0,1]]
Constraints:
1 <= colsum.length <= 10^50 <= upper, lower <= colsum.length0 <= colsum[i] <= 2Problem summary: Given the following details of a matrix with n columns and 2 rows : The matrix is a binary matrix, which means each element in the matrix can be 0 or 1. The sum of elements of the 0-th(upper) row is given as upper. The sum of elements of the 1-st(lower) row is given as lower. The sum of elements in the i-th column(0-indexed) is colsum[i], where colsum is given as an integer array with length n. Your task is to reconstruct the matrix with upper, lower and colsum. Return it as a 2-D integer array. If there are more than one valid solution, any of them will be accepted. If no valid solution exists, return an empty 2-D array.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Greedy
2 1 [1,1,1]
2 3 [2,2,1,1]
5 5 [2,1,2,0,1,0,1,2,0,1]
find-valid-matrix-given-row-and-column-sums)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1253: Reconstruct a 2-Row Binary Matrix
class Solution {
public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colsum) {
int n = colsum.length;
List<Integer> first = new ArrayList<>();
List<Integer> second = new ArrayList<>();
for (int j = 0; j < n; ++j) {
int a = 0, b = 0;
if (colsum[j] == 2) {
a = b = 1;
upper--;
lower--;
} else if (colsum[j] == 1) {
if (upper > lower) {
upper--;
a = 1;
} else {
lower--;
b = 1;
}
}
if (upper < 0 || lower < 0) {
break;
}
first.add(a);
second.add(b);
}
return upper == 0 && lower == 0 ? List.of(first, second) : List.of();
}
}
// Accepted solution for LeetCode #1253: Reconstruct a 2-Row Binary Matrix
func reconstructMatrix(upper int, lower int, colsum []int) [][]int {
n := len(colsum)
ans := make([][]int, 2)
for i := range ans {
ans[i] = make([]int, n)
}
for j, v := range colsum {
if v == 2 {
ans[0][j], ans[1][j] = 1, 1
upper--
lower--
}
if v == 1 {
if upper > lower {
upper--
ans[0][j] = 1
} else {
lower--
ans[1][j] = 1
}
}
if upper < 0 || lower < 0 {
break
}
}
if upper != 0 || lower != 0 {
return [][]int{}
}
return ans
}
# Accepted solution for LeetCode #1253: Reconstruct a 2-Row Binary Matrix
class Solution:
def reconstructMatrix(
self, upper: int, lower: int, colsum: List[int]
) -> List[List[int]]:
n = len(colsum)
ans = [[0] * n for _ in range(2)]
for j, v in enumerate(colsum):
if v == 2:
ans[0][j] = ans[1][j] = 1
upper, lower = upper - 1, lower - 1
if v == 1:
if upper > lower:
upper -= 1
ans[0][j] = 1
else:
lower -= 1
ans[1][j] = 1
if upper < 0 or lower < 0:
return []
return ans if lower == upper == 0 else []
// Accepted solution for LeetCode #1253: Reconstruct a 2-Row Binary Matrix
struct Solution;
impl Solution {
fn reconstruct_matrix(mut upper: i32, mut lower: i32, colsum: Vec<i32>) -> Vec<Vec<i32>> {
let n = colsum.len();
let mut res = vec![vec![0; n]; 2];
for j in 0..n {
match colsum[j] {
2 => {
res[0][j] = 1;
res[1][j] = 1;
upper -= 1;
lower -= 1;
}
1 => {
if upper >= lower {
res[0][j] = 1;
upper -= 1;
} else {
res[1][j] = 1;
lower -= 1;
}
}
_ => {}
}
}
if upper == 0 && lower == 0 {
res
} else {
vec![]
}
}
}
#[test]
fn test() {
let upper = 2;
let lower = 1;
let colsum = vec![1, 1, 1];
let res = vec_vec_i32![[1, 1, 0], [0, 0, 1]];
assert_eq!(Solution::reconstruct_matrix(upper, lower, colsum), res);
let upper = 2;
let lower = 3;
let colsum = vec![2, 2, 1, 1];
let res = vec_vec_i32![];
assert_eq!(Solution::reconstruct_matrix(upper, lower, colsum), res);
let upper = 5;
let lower = 5;
let colsum = vec![2, 1, 2, 0, 1, 0, 1, 2, 0, 1];
let res = vec_vec_i32![
[1, 1, 1, 0, 0, 0, 1, 1, 0, 0],
[1, 0, 1, 0, 1, 0, 0, 1, 0, 1]
];
assert_eq!(Solution::reconstruct_matrix(upper, lower, colsum), res);
}
// Accepted solution for LeetCode #1253: Reconstruct a 2-Row Binary Matrix
function reconstructMatrix(upper: number, lower: number, colsum: number[]): number[][] {
const n = colsum.length;
const ans: number[][] = Array(2)
.fill(0)
.map(() => Array(n).fill(0));
for (let j = 0; j < n; ++j) {
if (colsum[j] === 2) {
ans[0][j] = ans[1][j] = 1;
upper--;
lower--;
} else if (colsum[j] === 1) {
if (upper > lower) {
ans[0][j] = 1;
upper--;
} else {
ans[1][j] = 1;
lower--;
}
}
if (upper < 0 || lower < 0) {
break;
}
}
return upper || lower ? [] : ans;
}
Use this to step through a reusable interview workflow for this problem.
Try every possible combination of choices. With n items each having two states (include/exclude), the search space is 2ⁿ. Evaluating each combination takes O(n), giving O(n × 2ⁿ). The recursion stack or subset storage uses O(n) space.
Greedy algorithms typically sort the input (O(n log n)) then make a single pass (O(n)). The sort dominates. If the input is already sorted or the greedy choice can be computed without sorting, time drops to O(n). Proving greedy correctness (exchange argument) is harder than the implementation.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.