Largest 1-Bordered Rectangle
HardUpdated: Sep 20, 2025
Problem
Given a 2D binary matrix mat (values 0 or 1), find the area (number of cells) of the largest axis-aligned rectangle whose border cells are all 1. The interior of the rectangle may contain 0s.
Examples
Example 1
\begin{array}{|c|c|c|c|c|}
\hline
0 & {1} & 0 & 0 & 0 \\\
\hline
0 & {1} & 0 & 0 & 0 \\\
\hline
{1} & {\color{green}1} & {\color{green}1} & {\color{green}1} & 0 \\\
\hline
0 & {\color{green}1} & 0 & {\color{green}1} & 0 \\\
\hline
0 & {\color{green}1} & {\color{green}1} & {\color{green}1} & 0 \\\
\hline
\end{array}
Input:mat =
[
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 1, 1, 1, 0],
[0, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
]
Output: 9
Explanation: The bolded rectangle (3x3) has border of all 1s.
Solution
Method 1 — Brute force (enumerate all rectangles)
Intuition
Try every pair of rows r1 <= r2 and columns c1 <= c2 and explicitly check the four borders for 1s.
Approach
- For each
r1in0..n-1and eachr2inr1..n-1. - For each
c1in0..m-1and eachc2inc1..m-1. - Check the top row
mat[r1][c1..c2], bottom rowmat[r2][c1..c2], left columnmat[r1..r2][c1]and right columnmat[r1..r2][c2]are all1s. - If valid, update
ans = max(ans, (r2-r1+1)*(c2-c1+1)).
Code
C++
class Solution {
public:
int largest1BorderedRectangle(std::vector<std::vector<int>>& mat) {
int n = mat.size();
int m = mat[0].size();
int ans = 0;
for (int r1 = 0; r1 < n; ++r1) {
for (int r2 = r1; r2 < n; ++r2) {
for (int c1 = 0; c1 < m; ++c1) {
for (int c2 = c1; c2 < m; ++c2) {
bool ok = true;
for (int j = c1; j <= c2 && ok; ++j) {
if (!mat[r1][j] || !mat[r2][j]) ok = false;
}
for (int i = r1; i <= r2 && ok; ++i) {
if (!mat[i][c1] || !mat[i][c2]) ok = false;
}
if (ok) ans = std::max(ans, (r2 - r1 + 1) * (c2 - c1 + 1));
}
}
}
}
return ans;
}
};
Go
package main
func largest1BorderedRectangle(mat [][]int) int {
n := len(mat)
m := len(mat[0])
ans := 0
for r1 := 0; r1 < n; r1++ {
for r2 := r1; r2 < n; r2++ {
for c1 := 0; c1 < m; c1++ {
for c2 := c1; c2 < m; c2++ {
ok := true
for j := c1; j <= c2 && ok; j++ {
if mat[r1][j] == 0 || mat[r2][j] == 0 { ok = false }
}
for i := r1; i <= r2 && ok; i++ {
if mat[i][c1] == 0 || mat[i][c2] == 0 { ok = false }
}
if ok {
area := (r2 - r1 + 1) * (c2 - c1 + 1)
if area > ans { ans = area }
}
}
}
}
}
return ans
}
Java
class Solution {
public int largest1BorderedRectangle(int[][] mat) {
int n = mat.length, m = mat[0].length;
int ans = 0;
for (int r1 = 0; r1 < n; ++r1) {
for (int r2 = r1; r2 < n; ++r2) {
for (int c1 = 0; c1 < m; ++c1) {
for (int c2 = c1; c2 < m; ++c2) {
boolean ok = true;
for (int j = c1; j <= c2 && ok; ++j) {
if (mat[r1][j] == 0 || mat[r2][j] == 0) ok = false;
}
for (int i = r1; i <= r2 && ok; ++i) {
if (mat[i][c1] == 0 || mat[i][c2] == 0) ok = false;
}
if (ok) ans = Math.max(ans, (r2 - r1 + 1) * (c2 - c1 + 1));
}
}
}
}
return ans;
}
}
Python
class Solution:
def largest1BorderedRectangle(self, mat: list[list[int]]) -> int:
n = len(mat)
m = len(mat[0])
ans = 0
for r1 in range(n):
for r2 in range(r1, n):
for c1 in range(m):
for c2 in range(c1, m):
ok = True
for j in range(c1, c2+1):
if mat[r1][j] == 0 or mat[r2][j] == 0:
ok = False
break
if not ok:
continue
for i in range(r1, r2+1):
if mat[i][c1] == 0 or mat[i][c2] == 0:
ok = False
break
if ok:
ans = max(ans, (r2 - r1 + 1) * (c2 - c1 + 1))
return ans
Complexity
- ⏰ Time complexity:
O(n^4)— four nested loops enumerating rows and columns and border checks in O(n) are subsumed by the enumeration worst-case; for ann x nmatrix this is quartic. - 🧺 Space complexity:
O(1)additional space.
Method 2 — Precompute horizontal/vertical run-lengths
Intuition
Precompute at each cell hor[i][j] = number of consecutive 1s ending at (i,j) horizontally, and ver[i][j] = number of consecutive 1s ending at (i,j) vertically. For a candidate bottom-right corner (i,j), any rectangle of width w and height h ending at (i,j) is valid if hor[i][j] >= w, ver[i][j] >= h, ver[i][j-w+1] >= h and hor[i-h+1][j] >= w — each check is O(1).
Approach
- Build
horandverarrays inO(n*m). - For each cell
(i,j)as bottom-right corner, iterate possible heightsh = 1..ver[i][j]and widthsw = 1..hor[i][j](or iterate w/h in nested loops). For each pair check the four O(1) conditions above; updateans.
Code
C++
class Solution {
public:
int largest1BorderedRectangle(std::vector<std::vector<int>>& mat) {
int n = mat.size();
int m = mat[0].size();
std::vector<std::vector<int>> hor(n, std::vector<int>(m));
std::vector<std::vector<int>> ver(n, std::vector<int>(m));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (mat[i][j] == 1) {
hor[i][j] = (j ? hor[i][j-1] : 0) + 1;
ver[i][j] = (i ? ver[i-1][j] : 0) + 1;
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int h = 1; h <= ver[i][j]; ++h) {
for (int w = 1; w <= hor[i][j]; ++w) {
int r1 = i - h + 1;
int c1 = j - w + 1;
if (ver[i][c1] >= h && hor[r1][j] >= w) {
ans = std::max(ans, h * w);
}
}
}
}
}
return ans;
}
};
Go
package main
func largest1BorderedRectangle(mat [][]int) int {
n := len(mat)
m := len(mat[0])
hor := make([][]int, n)
ver := make([][]int, n)
for i := range hor { hor[i] = make([]int, m); ver[i] = make([]int, m) }
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if mat[i][j] == 1 {
if j > 0 { hor[i][j] = hor[i][j-1] + 1 } else { hor[i][j] = 1 }
if i > 0 { ver[i][j] = ver[i-1][j] + 1 } else { ver[i][j] = 1 }
}
}
}
ans := 0
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
for h := 1; h <= ver[i][j]; h++ {
for w := 1; w <= hor[i][j]; w++ {
r1 := i - h + 1
c1 := j - w + 1
if ver[i][c1] >= h && hor[r1][j] >= w {
area := h * w
if area > ans { ans = area }
}
}
}
}
}
return ans
}
Java
class Solution {
public int largest1BorderedRectangle(int[][] mat) {
int n = mat.length, m = mat[0].length;
int[][] hor = new int[n][m], ver = new int[n][m];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (mat[i][j] == 1) {
hor[i][j] = (j > 0 ? hor[i][j-1] : 0) + 1;
ver[i][j] = (i > 0 ? ver[i-1][j] : 0) + 1;
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int h = 1; h <= ver[i][j]; ++h) {
for (int w = 1; w <= hor[i][j]; ++w) {
int r1 = i - h + 1;
int c1 = j - w + 1;
if (ver[i][c1] >= h && hor[r1][j] >= w) ans = Math.max(ans, h * w);
}
}
}
}
return ans;
}
}
Python
class Solution:
def largest1BorderedRectangle(self, mat: list[list[int]]) -> int:
n = len(mat)
m = len(mat[0])
hor = [[0]*m for _ in range(n)]
ver = [[0]*m for _ in range(n)]
for i in range(n):
for j in range(m):
if mat[i][j] == 1:
hor[i][j] = (hor[i][j-1] if j>0 else 0) + 1
ver[i][j] = (ver[i-1][j] if i>0 else 0) + 1
ans = 0
for i in range(n):
for j in range(m):
for h in range(1, ver[i][j]+1):
for w in range(1, hor[i][j]+1):
r1 = i - h + 1
c1 = j - w + 1
if ver[i][c1] >= h and hor[r1][j] >= w:
ans = max(ans, h * w)
return ans
Complexity
- ⏰ Time complexity:
O(n^4)worst-case — preprocessing isO(n*m), but enumerating bottom-right corners and all possibleh,wyields quartic behavior for dense1matrices. - 🧺 Space complexity:
O(n*m)to storehorandver.