详细见:leetcode.com/problems/maximal-rectangle
Java Solution: github
package leetcode;
import java.util.Stack;
/*
* Given a 2D binary matrix filled with 0's and 1's,
* find the largest rectangle containing only 1's and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.
*/
public class P085_MaximalRectangle {
public static void main(String[] args) {
// System.out.println(new Solution().maxArea(new int[] {1, 2, 3, 2, 1}));
System.out.println(new Solution().maximalRectangle(new char[][] {
{'1','0','1','0','0'},
{'1','0','1','1','1'},
{'1','1','1','1','1'},
{'1','0','0','1','0'}
}));
System.out.println(new Solution().maximalRectangle(new char[][] {
{'1'}
}));
System.out.println(new Solution().maximalRectangle(new char[][] {
{'0', '1'},
{'1', '0'}
}));
}
/*
* AC
* 需要多学习栈
* 38 ms
*/
static class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return 0;
int[] heights = new int[matrix[0].length];
int maxArea = 0;
for (int i = 0; i != matrix.length; i ++) {
for (int j = 0; j != heights.length; j ++) {
heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0;
}
maxArea = Math.max(maxArea, maxArea(heights));
}
return maxArea;
}
int maxArea(int[] heights) {
if (heights == null || heights.length == 0)
return 0;
int maxArea = 0;
Stack<Integer> stk = new Stack<Integer>();
for (int i = 0; i != heights.length; i ++) {
while (! stk.isEmpty() && heights[i] < heights[stk.peek()]) {
int j = stk.pop();
int k = stk.isEmpty() ? -1 : stk.peek();
maxArea = Math.max(maxArea, (i - k - 1) * heights[j]);
}
stk.add(i);
}
while (! stk.isEmpty()) {
int j = stk.pop();
int k = stk.isEmpty() ? -1 : stk.peek();
maxArea = Math.max(maxArea, (heights.length - k - 1) * heights[j]);
}
return maxArea;
}
}
}
C Solution: github
/*
url: leetcode.com/problems/maximal-rectangle
AC 6ms 61.54%
*/
#include <stdio.h>
#include <stdlib.h>
int _max(int a, int b) {
return a < b ? b : a;
}
int rect(int* h, int* s, int n) {
int si = 0, i = 0, hv = 0, j = 0, l = 0, a = 0;
for (i = 0; i <= n; i ++) {
hv = i == n ? 0 : h[i];
if (si == 0 || hv > h[s[si - 1]]) {
s[si ++] = i;
} else {
j = s[si - 1];
si --;
l = si == 0 ? i : i - 1 - s[si - 1];
a = _max(a, h[j] * l);
i --;
}
}
return a;
}
int maximalRectangle(char** m, int rn, int cn) {
int* h = (int*) malloc(sizeof(int) * cn);
int i = 0, j = 0, a = 0;
int* s = (int*) malloc(sizeof(int) * cn);
for (j = 0; j < cn; j ++) h[j] = 0;
for (i = 0; i < rn; i ++) {
for (j = 0; j < cn; j ++)
h[j] = m[i][j] == '0' ? 0 : h[j] + 1;
for (j = 0; j < cn; j ++) s[j] = 0;
a = _max(a, rect(h, s, cn));
}
free(h);
free(s);
return a;
}
int main() {
char** m = (char**) malloc(sizeof(char*) * 4);
int rn = 4, cn = 5;
m[0] = "10100";
m[1] = "10111";
m[2] = "11111";
m[3] = "10010";
printf("answer is %d\r\n", maximalRectangle(m, rn, cn));
free(m);
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/maximal-rectangle
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年4月21日
@details: Solution: 155ms 64.34%
'''
class Solution(object):
def count(self, t, tn):
s, sn, i, a = [], 0, 0, 0
while i <= tn:
tv = 0 if i == tn else t[i]
if sn == 0 or t[s[sn-1]] <= tv:
s.append(i)
sn, i = sn+1, i+1
else:
j, sn = s.pop(), sn-1
l = i if sn == 0 else i-1-s[sn-1]
a = max(a, t[j] * l)
return a
def maximalRectangle(self, m):
"""
:type m: List[List[str]]
:rtype: int
"""
rn = 0 if m == None else len(m)
if rn == 0: return 0
cn = 0 if m[0] == None else len(m[0])
if cn == 0: return 0
t, a = [0] * cn, 0
for i in range(rn):
for j in range(cn):
if m[i][j] == '1': t[j] += 1
else: t[j] = 0
a = max(a, self.count(t, cn))
return a
if __name__ == "__main__":
m = [
['1','0','1','0','0'],
['1','0','1','1','1'],
['1','0','1','1','1'],
['1','1','1','1','1'],
['1','1','1','1','1'],
['1','0','0','1','0'],
]
print(Solution().maximalRectangle(m))