Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
此题初看是221题(http://blog.csdn.net/zmq570235977/article/details/51348028)的变式,实际上差别很大,难度也提升一个level。
下面的解法使用了84题(http://blog.csdn.net/zmq570235977/article/details/51354627)的方法
把每一个柱状“1”看成是条形bar,问题即可迎刃而解
public class Solution
{
public int MaximalRectangle(char[,] matrix)
{
int m = (int)matrix.GetLongLength(0);
int n = (int)matrix.GetLongLength(1);
if (m * n == 0)
return 0;
List<int> list = new List<int>();
int tmp,max = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i, j] != '0')
{
if (j==0||(j > 0 && matrix[i, j - 1] == '0'))
{
tmp = 0;
while (tmp <= i && matrix[i - tmp, j] != '0')
{
tmp++;
}
max = Math.Max(max, tmp);
}
else
{
list.Clear();
for (int k = j; k >= 0; k--)
{
if (matrix[i, k] == '0')
break;
tmp = 0;
while (tmp <= i && matrix[i - tmp, k] != '0')
{
tmp++;
}
list.Add(tmp);
}
list.Add(0);
max = Math.Max(max, Fun(list));
}
}
}
}
return max;
}
private int Fun(List<int> list)
{
int n = list.Count,i=0,max=0,tmp;
Stack<int> s = new Stack<int>();
while(i < n)
{
if (s.Count == 0 || list[s.Peek()] <= list[i])
s.Push(i++);
else
{
tmp = s.Pop();
max = Math.Max(max, list[tmp] * (s.Count == 0 ? i : i - s.Peek()-1));
}
}
return max;
}
}
加入动态规划进行优化:
public class Solution
{
public int MaximalRectangle(char[,] matrix)
{
int m = (int)matrix.GetLongLength(0);
int n = (int)matrix.GetLongLength(1);
if (m * n == 0)
return 0;
int[] height = new int[n + 1];
int max = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
height[j] = matrix[i,j] == '0' ? 0 : height[j] + 1;
}
max = Math.Max(max, Fun(height));
}
return max;
}
private int Fun(int[] list)
{
int n = list.Length,i=0,max=0,tmp;
Stack<int> s = new Stack<int>();
while(i < n)
{
if (s.Count == 0 || list[s.Peek()] <= list[i])
s.Push(i++);
else
{
tmp = s.Pop();
max = Math.Max(max, list[tmp] * (s.Count == 0 ? i : i - s.Peek()-1));
}
}
return max;
}
}