给定大小为N * M的二进制矩阵,任务是找到最大面积的子矩阵,以使其中的所有元素都相同,即全部为0或全部为1 。打印此类矩阵的最大可能区域。
例子:
Input: mat[][] = {
{1, 1, 0, 1, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 1, 1, 0, 0},
{0, 1, 1, 0, 1, 1, 0, 0},
{1, 0, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 1, 1} }
Output: 10
Largest submatrix with all equal elements starts from
mat[4][2] (top-left corner) and ends mat[5][6] (borrom-right corner).
Input: mat[][] = {
{1, 0},
{0, 1}}
Output: 1
方法:
- 尝试找到全为1的最大子矩阵,可以使用相同的方法查找全为0的最大子矩阵。
- 保持矩阵DP [N] [M],其中DP [i] [j]表示存在于第j个连续的1的数量列从第i行,直到最后一行开始。通过从底部到顶部遍历每一列,可以轻松地填充此矩阵。
- 现在,利用一个事实,即每行i,DP [i] [j]代表最大的连续1至第j列最后一行。现在,此问题与查找本文中已讨论的直方图中存在的最大面积矩形的问题相同。
- 必须将先前方法中提到的方法应用于矩阵的每一行,以找到最大面积子矩阵。
查找全为0的最大面积子矩阵的方法相同。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
#define row 6
#define col 8
using namespace std;
// Function to find the maximum rectangular
// area under given histogram with n bars
int cal(int hist[], int n)
{
// Create an empty stack. The stack holds indexes
// of hist[] array. The bars stored in stack are
// always in increasing order of their heights.
stack s;
// Initalize max area
int max_area = 0;
// To store top of the stack
int tp;
// To store area with top bar
int area_with_top;
// as the smallest bar
// Run through all bars of given histogram
int i = 0;
while (i < n) {
// If this bar is higher than the bar on top
// stack, push it to stack
if (s.empty() || hist[s.top()] <= hist[i])
s.push(i++);
// If this bar is lower than top of stack,
// then calculate area of rectangle with stack
// top as the smallest (or minimum height) bar.
// 'i' is 'right index' for the top and element
// before top in stack is 'left index'
else {
// Store the top index
tp = s.top();
// Pop the top
s.pop();
// Calculate the area with hist[tp] stack
// as smallest bar
area_with_top = hist[tp]
* (s.empty() ? i : i - s.top() - 1);
// Update max area, if needed
if (max_area < area_with_top)
max_area = area_with_top;
}
}
// Now pop the remaining bars from stack and calculate
// area with every popped bar as the smallest bar
while (s.empty() == false) {
tp = s.top();
s.pop();
area_with_top = hist[tp]
* (s.empty() ? i : i - s.top() - 1);
if (max_area < area_with_top)
max_area = area_with_top;
}
return max_area;
}
// Function to find largest sub matrix
// with all equal elements
int largestMatrix(int a[][col])
{
// To find largest sub matrix
// with all elements 1
int dp[row][col];
// Fill dp[][] by traversing each
// column from bottom to up
for (int i = 0; i < col; i++) {
int cnt = 0;
for (int j = row - 1; j >= 0; j--) {
dp[j][i] = 0;
if (a[j][i] == 1) {
cnt++;
dp[j][i] = cnt;
}
else {
cnt = 0;
}
}
}
int ans = -1;
for (int i = 0; i < row; i++) {
// Maintain the histogram array
int hist[col];
for (int j = 0; j < col; j++) {
hist[j] = dp[i][j];
}
// Find maximum area rectangle in Histogram
ans = max(ans, cal(hist, col));
}
// To fill dp[][] for finding largest
// sub matrix with all elements 0
for (int i = 0; i < col; i++) {
int cnt = 0;
for (int j = row - 1; j >= 0; j--) {
dp[j][i] = 0;
if (a[j][i] == 0) {
cnt++;
dp[j][i] = cnt;
}
else {
cnt = 0;
}
}
}
for (int i = 0; i < row; i++) {
// Maintain the histogram array
int hist[col];
for (int j = 0; j < col; j++) {
hist[j] = dp[i][j];
}
// Find maximum area rectangle in Histogram
ans = max(ans, cal(hist, col));
}
return ans;
}
// Driver code
int main()
{
int a[row][col] = { { 1, 1, 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0 },
{ 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 1 } };
cout << largestMatrix(a);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
static int row = 6;
static int col = 8;
// Function to find the maximum rectangular
// area under given histogram with n bars
static int cal(int hist[], int n)
{
// Create an empty stack. The stack holds indexes
// of hist[] array. The bars stored in stack are
// always in increasing order of their heights.
Stack s = new Stack<>();
// Initalize max area
int max_area = 0;
// To store top of the stack
int tp;
// To store area with top bar
int area_with_top;
// as the smallest bar
// Run through all bars of given histogram
int i = 0;
while (i < n)
{
// If this bar is higher than the bar on top
// stack, push it to stack
if (s.empty() || hist[s.peek()] <= hist[i])
s.push(i++);
// If this bar is lower than top of stack,
// then calculate area of rectangle with stack
// top as the smallest (or minimum height) bar.
// 'i' is 'right index' for the top and element
// before top in stack is 'left index'
else
{
// Store the top index
tp = s.peek();
// Pop the top
s.pop();
// Calculate the area with hist[tp] stack
// as smallest bar
area_with_top = hist[tp] * (s.empty() ? i :
i - s.peek() - 1);
// Update max area, if needed
if (max_area < area_with_top)
max_area = area_with_top;
}
}
// Now pop the remaining bars from stack and calculate
// area with every popped bar as the smallest bar
while (s.empty() == false)
{
tp = s.peek();
s.pop();
area_with_top = hist[tp] * (s.empty() ? i :
i - s.peek() - 1);
if (max_area < area_with_top)
max_area = area_with_top;
}
return max_area;
}
// Function to find largest sub matrix
// with all equal elements
static int largestMatrix(int a[][])
{
// To find largest sub matrix
// with all elements 1
int [][]dp = new int[row][col];
// Fill dp[][] by traversing each
// column from bottom to up
for (int i = 0; i < col; i++)
{
int cnt = 0;
for (int j = row - 1; j >= 0; j--)
{
dp[j][i] = 0;
if (a[j][i] == 1)
{
cnt++;
dp[j][i] = cnt;
}
else
{
cnt = 0;
}
}
}
int ans = -1;
for (int i = 0; i < row; i++)
{
// Maintain the histogram array
int []hist = new int[col];
for (int j = 0; j < col; j++)
{
hist[j] = dp[i][j];
}
// Find maximum area rectangle in Histogram
ans = Math.max(ans, cal(hist, col));
}
// To fill dp[][] for finding largest
// sub matrix with all elements 0
for (int i = 0; i < col; i++)
{
int cnt = 0;
for (int j = row - 1; j >= 0; j--)
{
dp[j][i] = 0;
if (a[j][i] == 0)
{
cnt++;
dp[j][i] = cnt;
}
else
{
cnt = 0;
}
}
}
for (int i = 0; i < row; i++)
{
// Maintain the histogram array
int []hist = new int[col];
for (int j = 0; j < col; j++)
{
hist[j] = dp[i][j];
}
// Find maximum area rectangle in Histogram
ans = Math.max(ans, cal(hist, col));
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int a[][] = {{ 1, 1, 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0 },
{ 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 1 }};
System.out.println(largestMatrix(a));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python 3 implementation of the approach
row = 6
col = 8
# Function to find the maximum rectangular
# area under given histogram with n bars
def cal(hist, n):
# Create an empty stack. The stack holds indexes
# of hist[] array. The bars stored in stack are
# always in increasing order of their heights.
s = [];
# Initalize max area
max_area = 0
# Run through all bars of given histogram
i = 0
while (i < n) :
# If this bar is higher than the bar on top
# stack, push it to stack
if (len(s) == 0 or( hist[s[-1]] <= hist[i])):
s.append(i)
i += 1
# If this bar is lower than top of stack,
# then calculate area of rectangle with stack
# top as the smallest (or minimum height) bar.
# 'i' is 'right index' for the top and element
# before top in stack is 'left index'
else :
# Store the top index
tp = s[-1]
# Pop the top
s.pop()
# Calculate the area with hist[tp] stack
# as smallest bar
if len(s) == 0:
area_with_top = hist[tp]*i
else:
area_with_top = hist[tp]*(i -s[-1] - 1)
# Update max area, if needed
if (max_area < area_with_top):
max_area = area_with_top
# Now pop the remaining bars from stack and calculate
# area with every popped bar as the smallest bar
while (len(s)!=0):
tp = s[-1]
s.pop()
if len(s)==0:
area_with_top = hist[tp]*i
else:
area_with_top = hist[tp]*(i - s[-1] - 1)
if (max_area < area_with_top):
max_area = area_with_top
return max_area
# Function to find largest sub matrix
# with all equal elements
def largestMatrix(a):
# To find largest sub matrix
# with all elements 1
dp = [[ 0 for x in range(col)] for y in range(row)]
# Fill dp[][] by traversing each
# column from bottom to up
for i in range(col):
cnt = 0
for j in range( row - 1, -1 ,-1):
dp[j][i] = 0
if (a[j][i] == 1) :
cnt+=1
dp[j][i] = cnt
else :
cnt = 0
# print("cnt ",cnt)
ans = -1
for i in range( row ):
# Maintain the histogram array
hist = [0]*col
for j in range(col):
hist[j] = dp[i][j]
# Find maximum area rectangle in Histogram
ans = max(ans, cal(hist, col))
# To fill dp[][] for finding largest
# sub matrix with all elements 0
for i in range( col):
cnt = 0
for j in range( row - 1, -1 ,-1):
dp[j][i] = 0
if (a[j][i] == 0):
cnt +=1
dp[j][i] = cnt
else:
cnt = 0
for i in range( row) :
# Maintain the histogram array
hist = [0]*col
for j in range(col):
hist[j] = dp[i][j]
# Find maximum area rectangle in Histogram
ans = max(ans, cal(hist, col))
return ans
# Driver code
if __name__ == "__main__":
a = [ [1, 1, 0, 1, 0, 0, 0, 0 ],
[ 0, 1, 1, 1, 1, 0, 0, 1 ],
[ 1, 0, 0, 1, 1, 1, 0, 0 ],
[ 0, 1, 1, 0, 1, 1, 0, 0 ],
[ 1, 0, 1, 1, 1, 1, 1, 0 ],
[ 0, 0, 1, 1, 1, 1, 1, 1 ]]
print(largestMatrix(a))
# This code is contributed by chitranayal
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
static int row = 6;
static int col = 8;
// Function to find the maximum rectangular
// area under given histogram with n bars
static int cal(int []hist, int n)
{
// Create an empty stack. The stack holds indexes
// of hist[] array. The bars stored in stack are
// always in increasing order of their heights.
Stack s = new Stack();
// Initalize max area
int max_area = 0;
// To store top of the stack
int tp;
// To store area with top bar
int area_with_top;
// as the smallest bar
// Run through all bars of given histogram
int i = 0;
while (i < n)
{
// If this bar is higher than the bar on top
// stack, push it to stack
if (s.Count == 0 || hist[s.Peek()] <= hist[i])
s.Push(i++);
// If this bar is lower than top of stack,
// then calculate area of rectangle with stack
// top as the smallest (or minimum height) bar.
// 'i' is 'right index' for the top and element
// before top in stack is 'left index'
else
{
// Store the top index
tp = s.Peek();
// Pop the top
s.Pop();
// Calculate the area with hist[tp] stack
// as smallest bar
area_with_top = hist[tp] * (s.Count == 0 ? i :
i - s.Peek() - 1);
// Update max area, if needed
if (max_area < area_with_top)
max_area = area_with_top;
}
}
// Now pop the remaining bars from stack and calculate
// area with every popped bar as the smallest bar
while (s.Count == 0 == false)
{
tp = s.Peek();
s.Pop();
area_with_top = hist[tp] * (s.Count == 0 ? i :
i - s.Peek() - 1);
if (max_area < area_with_top)
max_area = area_with_top;
}
return max_area;
}
// Function to find largest sub matrix
// with all equal elements
static int largestMatrix(int [,]a)
{
// To find largest sub matrix
// with all elements 1
int [,]dp = new int[row, col];
// Fill dp[,] by traversing each
// column from bottom to up
for (int i = 0; i < col; i++)
{
int cnt = 0;
for (int j = row - 1; j >= 0; j--)
{
dp[j, i] = 0;
if (a[j, i] == 1)
{
cnt++;
dp[j, i] = cnt;
}
else
{
cnt = 0;
}
}
}
int ans = -1;
for (int i = 0; i < row; i++)
{
// Maintain the histogram array
int []hist = new int[col];
for (int j = 0; j < col; j++)
{
hist[j] = dp[i, j];
}
// Find maximum area rectangle in Histogram
ans = Math.Max(ans, cal(hist, col));
}
// To fill dp[,] for finding largest
// sub matrix with all elements 0
for (int i = 0; i < col; i++)
{
int cnt = 0;
for (int j = row - 1; j >= 0; j--)
{
dp[j, i] = 0;
if (a[j, i] == 0)
{
cnt++;
dp[j, i] = cnt;
}
else
{
cnt = 0;
}
}
}
for (int i = 0; i < row; i++)
{
// Maintain the histogram array
int []hist = new int[col];
for (int j = 0; j < col; j++)
{
hist[j] = dp[i, j];
}
// Find maximum area rectangle in Histogram
ans = Math.Max(ans, cal(hist, col));
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
int [,]a = {{ 1, 1, 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0 },
{ 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 1 }};
Console.WriteLine(largestMatrix(a));
}
}
// This code is contributed by 29AjayKumar
输出:
10