Given a 2D binary matrix mat[][] consisting only of 0s and 1s, find the area of the largest rectangle sub-matrix that contains only 1s.
Examples:
Input: mat[][] = [[0, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 0, 0]] Output: 8 Explanation: The largest rectangle with only 1's is from (1, 0) to (2, 3) which is
Input: mat[][] = [[0, 1, 1], [1, 1, 1], [0, 1, 1]] Output: 6 Explanation: The largest rectangle with only 1's is from (0, 1) to (2, 2) which is
[Approach 1] Using Largest Rectangular Area in a Histogram - O(n*m) Time and O(m) Space
Instead of directly searching the whole matrix, think row by row. For every row, treat it as the base of a rectangle and see how far rectangles of 1’s can extend upward.
Build Heights Array
Maintain an array height[] where height[j] stores the count of consecutive 1’s in column j up to the current row.
If you encounter a 0, reset that column’s height to 0.
Now, after updating height[] for a row, the problem becomes identical to finding the largest rectangle area in a histogram formed by height[].
The idea is to treat each row as the ground and encode vertical runs of 1’s into a histogram (height[]). Then the known stack-based largest-rectangle-in-histogram gives the max area for that base repeat for all rows and take the max.
C++
#include<iostream>#include<vector>#include<stack>#include<algorithm>usingnamespacestd;// Function to find the maximum area of // rectangle in a histogram.intgetMaxArea(vector<int>&heights){intn=heights.size();stack<int>s;intres=0;for(inti=0;i<n;i++){// Process all bars that are higher or equal to currentwhile(!s.empty()&&heights[s.top()]>=heights[i]){inttp=s.top();s.pop();// Width between previous smaller (stack top) and current indexintwidth=s.empty()?i:i-s.top()-1;res=max(res,heights[tp]*width);}s.push(i);}// Process remaining bars in stackwhile(!s.empty()){inttp=s.top();s.pop();intwidth=s.empty()?n:n-s.top()-1;res=max(res,heights[tp]*width);}returnres;}// Function to find the maximum area of rectangle// in a 2D matrix.intmaxArea(vector<vector<int>>&mat){intn=mat.size(),m=mat[0].size();// heights will store histogram heightsvector<int>heights(m,0);intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Update histogram heightsif(mat[i][j]==1)heights[j]++;elseheights[j]=0;}ans=max(ans,getMaxArea(heights));}returnans;}intmain(){vector<vector<int>>mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};cout<<maxArea(mat)<<endl;return0;}
Java
importjava.util.Stack;publicclassGFG{// Function to find the maximum area of // rectangle in a histogram.staticintgetMaxArea(int[]heights){intn=heights.length;Stack<Integer>s=newStack<>();intres=0;for(inti=0;i<n;i++){// Process all bars that are higher or equal to currentwhile(!s.isEmpty()&&heights[s.peek()]>=heights[i]){inttp=s.pop();// Width between previous smaller (stack top) and current indexintwidth=s.isEmpty()?i:i-s.peek()-1;res=Math.max(res,heights[tp]*width);}s.push(i);}// Process remaining bars in stackwhile(!s.isEmpty()){inttp=s.pop();intwidth=s.isEmpty()?n:n-s.peek()-1;res=Math.max(res,heights[tp]*width);}returnres;}// Function to find the maximum area of rectangle// in a 2D matrix.staticintmaxArea(int[][]mat){intn=mat.length,m=mat[0].length;// heights will store histogram heightsint[]heights=newint[m];intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Update histogram heightsif(mat[i][j]==1)heights[j]++;elseheights[j]=0;}ans=Math.max(ans,getMaxArea(heights));}returnans;}publicstaticvoidmain(String[]args){int[][]mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};System.out.println(maxArea(mat));}}
Python
# Function to find the maximum area of # rectangle in a histogram.defgetMaxArea(heights):n=len(heights)s=[]res=0foriinrange(n):# Process all bars that are higher or equal to currentwhilesandheights[s[-1]]>=heights[i]:tp=s.pop()# Width between previous smaller (stack top) and current indexwidth=iifnotselsei-s[-1]-1res=max(res,heights[tp]*width)s.append(i)# Process remaining bars in stackwhiles:tp=s.pop()width=nifnotselsen-s[-1]-1res=max(res,heights[tp]*width)returnres# Function to find the maximum area of rectangle# in a 2D matrix.defmaxArea(mat):n,m=len(mat),len(mat[0])# heights will store histogram heightsheights=[0]*mans=0foriinrange(n):forjinrange(m):# Update histogram heightsifmat[i][j]==1:heights[j]+=1else:heights[j]=0ans=max(ans,getMaxArea(heights))returnansif__name__=="__main__":mat=[[0,1,1,0],[1,1,1,1],[1,1,1,1],[1,1,0,0]]print(maxArea(mat))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to find the maximum area of // rectangle in a histogram.staticintgetMaxArea(int[]heights){intn=heights.Length;Stack<int>s=newStack<int>();intres=0;for(inti=0;i<n;i++){// Process all bars that are higher or equal to currentwhile(s.Count>0&&heights[s.Peek()]>=heights[i]){inttp=s.Pop();// Width between previous smaller (stack top) and current indexintwidth=(s.Count==0)?i:i-s.Peek()-1;res=Math.Max(res,heights[tp]*width);}s.Push(i);}// Process remaining bars in stackwhile(s.Count>0){inttp=s.Pop();intwidth=(s.Count==0)?n:n-s.Peek()-1;res=Math.Max(res,heights[tp]*width);}returnres;}// Function to find the maximum area of rectangle// in a 2D matrix.staticintmaxArea(int[,]mat){intn=mat.GetLength(0),m=mat.GetLength(1);// heights will store histogram heightsint[]heights=newint[m];intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){// Update histogram heightsif(mat[i,j]==1)heights[j]++;elseheights[j]=0;}ans=Math.Max(ans,getMaxArea(heights));}returnans;}staticvoidMain(){int[,]mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};Console.WriteLine(maxArea(mat));}}
JavaScript
// Function to find the maximum area of // rectangle in a histogram.functiongetMaxArea(heights){letn=heights.length;lets=[];letres=0;for(leti=0;i<n;i++){// Process all bars that are higher or equal to currentwhile(s.length>0&&heights[s[s.length-1]]>=heights[i]){lettp=s.pop();// Width between previous smaller (stack top) and current indexletwidth=(s.length===0)?i:i-s[s.length-1]-1;res=Math.max(res,heights[tp]*width);}s.push(i);}// Process remaining bars in stackwhile(s.length>0){lettp=s.pop();letwidth=(s.length===0)?n:n-s[s.length-1]-1;res=Math.max(res,heights[tp]*width);}returnres;}// Function to find the maximum area of rectangle// in a 2D matrix.functionmaxArea(mat){letn=mat.length,m=mat[0].length;// heights will store histogram heightsletheights=newArray(m).fill(0);letans=0;for(leti=0;i<n;i++){for(letj=0;j<m;j++){// Update histogram heightsif(mat[i][j]===1)heights[j]++;elseheights[j]=0;}ans=Math.max(ans,getMaxArea(heights));}returnans;}// Driver Codeletmat=[[0,1,1,0],[1,1,1,1],[1,1,1,1],[1,1,0,0]];console.log(maxArea(mat));
Output
8
[Approach 2] Using Dynamic Programming - O((n^2)*m) Time and O(n*m) Space
The idea is to store, for each cell (i, j), the width of consecutive 1’s ending at that position in a 2D array. Then, for every cell (i, j) with value 1, iterate upwards row by row. While moving upward, keep track of the minimum width of 1’s seen so far in that column. This ensures the rectangle formed remains valid. At each step, the rectangle area is computed as: (area = minWidth * height)
C++
#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;intmaxArea(vector<vector<int>>&mat){intn=mat.size(),m=mat[0].size();// memo[i][j] stores the width of consecutive 1's// ending at position (i, j).vector<vector<int>>memo(n,vector<int>(m,0));intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==0)continue;// Compute width of 1's at (i, j).memo[i][j]=(j==0)?1:memo[i][j-1]+1;intwidth=memo[i][j];// Traverse upwards row by row,// update minimum width and calculate area.for(intk=i;k>=0;k--){width=min(width,memo[k][j]);intarea=width*(i-k+1);ans=max(ans,area);}}}returnans;}intmain(){vector<vector<int>>mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};cout<<maxArea(mat)<<endl;return0;}
Java
publicclassGFG{staticintmaxArea(int[][]mat){intn=mat.length,m=mat[0].length;// memo[i][j] stores the width of consecutive 1's// ending at position (i, j).int[][]memo=newint[n][m];intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i][j]==0)continue;// Compute width of 1's at (i, j).memo[i][j]=(j==0)?1:memo[i][j-1]+1;intwidth=memo[i][j];// Traverse upwards row by row,// update minimum width and calculate area.for(intk=i;k>=0;k--){width=Math.min(width,memo[k][j]);intarea=width*(i-k+1);ans=Math.max(ans,area);}}}returnans;}publicstaticvoidmain(String[]args){int[][]mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};System.out.println(maxArea(mat));}}
Python
defmaxArea(mat):n,m=len(mat),len(mat[0])# memo[i][j] stores the width of consecutive 1's# ending at position (i, j).memo=[[0]*mfor_inrange(n)]ans=0foriinrange(n):forjinrange(m):ifmat[i][j]==0:continue# Compute width of 1's at (i, j).memo[i][j]=1ifj==0elsememo[i][j-1]+1width=memo[i][j]# Traverse upwards row by row,# update minimum width and calculate area.forkinrange(i,-1,-1):width=min(width,memo[k][j])area=width*(i-k+1)ans=max(ans,area)returnansif__name__=="__main__":mat=[[0,1,1,0],[1,1,1,1],[1,1,1,1],[1,1,0,0]]print(maxArea(mat))
C#
usingSystem;classGFG{staticintmaxArea(int[,]mat){intn=mat.GetLength(0),m=mat.GetLength(1);// memo[i][j] stores the width of consecutive 1's// ending at position (i, j).int[,]memo=newint[n,m];intans=0;for(inti=0;i<n;i++){for(intj=0;j<m;j++){if(mat[i,j]==0)continue;// Compute width of 1's at (i, j).memo[i,j]=(j==0)?1:memo[i,j-1]+1;intwidth=memo[i,j];// Traverse upwards row by row,// update minimum width and calculate area.for(intk=i;k>=0;k--){width=Math.Min(width,memo[k,j]);intarea=width*(i-k+1);ans=Math.Max(ans,area);}}}returnans;}staticvoidMain(){int[,]mat={{0,1,1,0},{1,1,1,1},{1,1,1,1},{1,1,0,0}};Console.WriteLine(maxArea(mat));}}
JavaScript
functionmaxArea(mat){constn=mat.length,m=mat[0].length;// memo[i][j] stores the width of consecutive 1's// ending at position (i, j).constmemo=Array.from({length:n},()=>Array(m).fill(0));letans=0;for(leti=0;i<n;i++){for(letj=0;j<m;j++){if(mat[i][j]===0)continue;// Compute width of 1's at (i, j).memo[i][j]=(j===0)?1:memo[i][j-1]+1;letwidth=memo[i][j];// Traverse upwards row by row,// update minimum width and calculate area.for(letk=i;k>=0;k--){width=Math.min(width,memo[k][j]);constarea=width*(i-k+1);ans=Math.max(ans,area);}}}returnans;}// Driver Codeconstmat=[[0,1,1,0],[1,1,1,1],[1,1,1,1],[1,1,0,0]];console.log(maxArea(mat));