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.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given a 2D binary array grid. You need to find 3 non-overlapping rectangles having non-zero areas with horizontal and vertical sides such that all the 1's in grid lie inside these rectangles.
Return the minimum possible sum of the area of these rectangles.
Note that the rectangles are allowed to touch.
Example 1:
Input: grid = [[1,0,1],[1,1,1]]
Output: 5
Explanation:
(0, 0) and (1, 0) are covered by a rectangle of area 2.(0, 2) and (1, 2) are covered by a rectangle of area 2.(1, 1) is covered by a rectangle of area 1.Example 2:
Input: grid = [[1,0,1,0],[0,1,0,1]]
Output: 5
Explanation:
(0, 0) and (0, 2) are covered by a rectangle of area 3.(1, 1) is covered by a rectangle of area 1.(1, 3) is covered by a rectangle of area 1.Constraints:
1 <= grid.length, grid[i].length <= 30grid[i][j] is either 0 or 1.grid.Problem summary: You are given a 2D binary array grid. You need to find 3 non-overlapping rectangles having non-zero areas with horizontal and vertical sides such that all the 1's in grid lie inside these rectangles. Return the minimum possible sum of the area of these rectangles. Note that the rectangles are allowed to touch.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[[1,0,1],[1,1,1]]
[[1,0,1,0],[0,1,0,1]]
smallest-rectangle-enclosing-black-pixels)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3197: Find the Minimum Area to Cover All Ones II
class Solution {
private final int inf = 1 << 30;
private int[][] grid;
public int minimumSum(int[][] grid) {
this.grid = grid;
int m = grid.length;
int n = grid[0].length;
int ans = m * n;
for (int i1 = 0; i1 < m - 1; i1++) {
for (int i2 = i1 + 1; i2 < m - 1; i2++) {
ans = Math.min(
ans, f(0, 0, i1, n - 1) + f(i1 + 1, 0, i2, n - 1) + f(i2 + 1, 0, m - 1, n - 1));
}
}
for (int j1 = 0; j1 < n - 1; j1++) {
for (int j2 = j1 + 1; j2 < n - 1; j2++) {
ans = Math.min(
ans, f(0, 0, m - 1, j1) + f(0, j1 + 1, m - 1, j2) + f(0, j2 + 1, m - 1, n - 1));
}
}
for (int i = 0; i < m - 1; i++) {
for (int j = 0; j < n - 1; j++) {
ans = Math.min(
ans, f(0, 0, i, j) + f(0, j + 1, i, n - 1) + f(i + 1, 0, m - 1, n - 1));
ans = Math.min(
ans, f(0, 0, i, n - 1) + f(i + 1, 0, m - 1, j) + f(i + 1, j + 1, m - 1, n - 1));
ans = Math.min(
ans, f(0, 0, i, j) + f(i + 1, 0, m - 1, j) + f(0, j + 1, m - 1, n - 1));
ans = Math.min(
ans, f(0, 0, m - 1, j) + f(0, j + 1, i, n - 1) + f(i + 1, j + 1, m - 1, n - 1));
}
}
return ans;
}
private int f(int i1, int j1, int i2, int j2) {
int x1 = inf, y1 = inf;
int x2 = -inf, y2 = -inf;
for (int i = i1; i <= i2; i++) {
for (int j = j1; j <= j2; j++) {
if (grid[i][j] == 1) {
x1 = Math.min(x1, i);
y1 = Math.min(y1, j);
x2 = Math.max(x2, i);
y2 = Math.max(y2, j);
}
}
}
return (x2 - x1 + 1) * (y2 - y1 + 1);
}
}
// Accepted solution for LeetCode #3197: Find the Minimum Area to Cover All Ones II
func minimumSum(grid [][]int) int {
m := len(grid)
n := len(grid[0])
ans := m * n
inf := math.MaxInt32
f := func(i1, j1, i2, j2 int) int {
x1, y1 := inf, inf
x2, y2 := -inf, -inf
for i := i1; i <= i2; i++ {
for j := j1; j <= j2; j++ {
if grid[i][j] == 1 {
x1 = min(x1, i)
y1 = min(y1, j)
x2 = max(x2, i)
y2 = max(y2, j)
}
}
}
if x1 == inf {
return 0
}
return (x2 - x1 + 1) * (y2 - y1 + 1)
}
for i1 := 0; i1 < m-1; i1++ {
for i2 := i1 + 1; i2 < m-1; i2++ {
ans = min(ans, f(0, 0, i1, n-1)+f(i1+1, 0, i2, n-1)+f(i2+1, 0, m-1, n-1))
}
}
for j1 := 0; j1 < n-1; j1++ {
for j2 := j1 + 1; j2 < n-1; j2++ {
ans = min(ans, f(0, 0, m-1, j1)+f(0, j1+1, m-1, j2)+f(0, j2+1, m-1, n-1))
}
}
for i := 0; i < m-1; i++ {
for j := 0; j < n-1; j++ {
ans = min(ans, f(0, 0, i, j)+f(0, j+1, i, n-1)+f(i+1, 0, m-1, n-1))
ans = min(ans, f(0, 0, i, n-1)+f(i+1, 0, m-1, j)+f(i+1, j+1, m-1, n-1))
ans = min(ans, f(0, 0, i, j)+f(i+1, 0, m-1, j)+f(0, j+1, m-1, n-1))
ans = min(ans, f(0, 0, m-1, j)+f(0, j+1, i, n-1)+f(i+1, j+1, m-1, n-1))
}
}
return ans
}
# Accepted solution for LeetCode #3197: Find the Minimum Area to Cover All Ones II
class Solution:
def minimumSum(self, grid: List[List[int]]) -> int:
def f(i1: int, j1: int, i2: int, j2: int) -> int:
x1 = y1 = inf
x2 = y2 = -inf
for i in range(i1, i2 + 1):
for j in range(j1, j2 + 1):
if grid[i][j] == 1:
x1 = min(x1, i)
y1 = min(y1, j)
x2 = max(x2, i)
y2 = max(y2, j)
return (x2 - x1 + 1) * (y2 - y1 + 1)
m, n = len(grid), len(grid[0])
ans = m * n
for i1 in range(m - 1):
for i2 in range(i1 + 1, m - 1):
ans = min(
ans,
f(0, 0, i1, n - 1)
+ f(i1 + 1, 0, i2, n - 1)
+ f(i2 + 1, 0, m - 1, n - 1),
)
for j1 in range(n - 1):
for j2 in range(j1 + 1, n - 1):
ans = min(
ans,
f(0, 0, m - 1, j1)
+ f(0, j1 + 1, m - 1, j2)
+ f(0, j2 + 1, m - 1, n - 1),
)
for i in range(m - 1):
for j in range(n - 1):
ans = min(
ans,
f(0, 0, i, j) + f(0, j + 1, i, n - 1) + f(i + 1, 0, m - 1, n - 1),
)
ans = min(
ans,
f(0, 0, i, n - 1)
+ f(i + 1, 0, m - 1, j)
+ f(i + 1, j + 1, m - 1, n - 1),
)
ans = min(
ans,
f(0, 0, i, j) + f(i + 1, 0, m - 1, j) + f(0, j + 1, m - 1, n - 1),
)
ans = min(
ans,
f(0, 0, m - 1, j)
+ f(0, j + 1, i, n - 1)
+ f(i + 1, j + 1, m - 1, n - 1),
)
return ans
// Accepted solution for LeetCode #3197: Find the Minimum Area to Cover All Ones II
impl Solution {
pub fn minimum_sum(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
let mut ans = (m * n) as i32;
let inf = i32::MAX / 4;
let f = |i1: usize, j1: usize, i2: usize, j2: usize| -> i32 {
let mut x1 = inf;
let mut y1 = inf;
let mut x2 = -inf;
let mut y2 = -inf;
for i in i1..=i2 {
for j in j1..=j2 {
if grid[i][j] == 1 {
x1 = x1.min(i as i32);
y1 = y1.min(j as i32);
x2 = x2.max(i as i32);
y2 = y2.max(j as i32);
}
}
}
if x1 > x2 || y1 > y2 {
inf
} else {
(x2 - x1 + 1) * (y2 - y1 + 1)
}
};
for i1 in 0..m - 1 {
for i2 in i1 + 1..m - 1 {
ans = ans
.min(f(0, 0, i1, n - 1) + f(i1 + 1, 0, i2, n - 1) + f(i2 + 1, 0, m - 1, n - 1));
}
}
for j1 in 0..n - 1 {
for j2 in j1 + 1..n - 1 {
ans = ans
.min(f(0, 0, m - 1, j1) + f(0, j1 + 1, m - 1, j2) + f(0, j2 + 1, m - 1, n - 1));
}
}
for i in 0..m - 1 {
for j in 0..n - 1 {
ans = ans.min(f(0, 0, i, j) + f(0, j + 1, i, n - 1) + f(i + 1, 0, m - 1, n - 1));
ans = ans
.min(f(0, 0, i, n - 1) + f(i + 1, 0, m - 1, j) + f(i + 1, j + 1, m - 1, n - 1));
ans = ans.min(f(0, 0, i, j) + f(i + 1, 0, m - 1, j) + f(0, j + 1, m - 1, n - 1));
ans = ans
.min(f(0, 0, m - 1, j) + f(0, j + 1, i, n - 1) + f(i + 1, j + 1, m - 1, n - 1));
}
}
ans
}
}
// Accepted solution for LeetCode #3197: Find the Minimum Area to Cover All Ones II
function minimumSum(grid: number[][]): number {
const m = grid.length;
const n = grid[0].length;
let ans = m * n;
const inf = Number.MAX_SAFE_INTEGER;
const f = (i1: number, j1: number, i2: number, j2: number): number => {
let [x1, y1] = [inf, inf];
let [x2, y2] = [-inf, -inf];
for (let i = i1; i <= i2; i++) {
for (let j = j1; j <= j2; j++) {
if (grid[i][j] === 1) {
x1 = Math.min(x1, i);
y1 = Math.min(y1, j);
x2 = Math.max(x2, i);
y2 = Math.max(y2, j);
}
}
}
return x1 === inf ? 0 : (x2 - x1 + 1) * (y2 - y1 + 1);
};
for (let i1 = 0; i1 < m - 1; i1++) {
for (let i2 = i1 + 1; i2 < m - 1; i2++) {
ans = Math.min(
ans,
f(0, 0, i1, n - 1) + f(i1 + 1, 0, i2, n - 1) + f(i2 + 1, 0, m - 1, n - 1),
);
}
}
for (let j1 = 0; j1 < n - 1; j1++) {
for (let j2 = j1 + 1; j2 < n - 1; j2++) {
ans = Math.min(
ans,
f(0, 0, m - 1, j1) + f(0, j1 + 1, m - 1, j2) + f(0, j2 + 1, m - 1, n - 1),
);
}
}
for (let i = 0; i < m - 1; i++) {
for (let j = 0; j < n - 1; j++) {
ans = Math.min(ans, f(0, 0, i, j) + f(0, j + 1, i, n - 1) + f(i + 1, 0, m - 1, n - 1));
ans = Math.min(
ans,
f(0, 0, i, n - 1) + f(i + 1, 0, m - 1, j) + f(i + 1, j + 1, m - 1, n - 1),
);
ans = Math.min(ans, f(0, 0, i, j) + f(i + 1, 0, m - 1, j) + f(0, j + 1, m - 1, n - 1));
ans = Math.min(
ans,
f(0, 0, m - 1, j) + f(0, j + 1, i, n - 1) + f(i + 1, j + 1, m - 1, n - 1),
);
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
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.