1 class Solution {
 2     public int maximalRectangle(char[][] matrix) {
 3         if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
 4         
 5         int[] height = new int[matrix[0].length];
 6         for(int i = 0; i < matrix[0].length; i ++){
 7             if(matrix[0][i] == '1') height[i] = 1;
 8         }
 9         int result = largestInLine(height);
10         for(int i = 1; i < matrix.length; i ++){
11             resetHeight(matrix, height, i);
12             result = Math.max(result, largestInLine(height));
13         }
14         
15         return result;
16     }
17 
18     private void resetHeight(char[][] matrix, int[] height, int idx){
19         for(int i = 0; i < matrix[0].length; i ++){
20             if(matrix[idx][i] == '1') height[i] += 1;
21             else height[i] = 0;
22         }
23     }    
24 
25     public int largestInLine(int[] height) {
26         if(height == null || height.length == 0) return 0;
27         int len = height.length;
28         Stack<Integer> s = new Stack<Integer>();
29         int maxArea = 0;
30         for(int i = 0; i <= len; i++){
31             int h = (i == len ? 0 : height[i]);
32             if(s.isEmpty() || h >= height[s.peek()]){
33                 s.push(i);
34             }else{
35                 int tp = s.pop();
36                 maxArea = Math.max(maxArea, height[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));
37                 i--;
38             }
39         }
40         return maxArea;
41     }
42 }

参考:https://leetcode.com/problems/maximal-rectangle/discuss/29055/My-java-solution-based-on-Maximum-Rectangle-in-Histogram-with-explanation

补充一个python的实现:

 1 class Solution:
 2     def maximalRectangle(self, matrix: 'List[List[str]]') -> int:
 3         if matrix == None:
 4             return 0
 5         row = len(matrix)
 6         if row == 0:
 7             return 0
 8         column = len(matrix[0])
 9         if column == 0:
10             return 0
11         heights = [0] * column
12         for i in range(column):
13             if matrix[0][i] == '1':
14                 heights[i] = 1
15         result = self.largestRectangleArea(heights)
16         for i in range(1,row):
17             self.resetHeight(matrix,heights,i)
18             result = max(result,self.largestRectangleArea(heights))
19         return result
20 
21     def largestRectangleArea(self, heights: 'List[int]') -> int:
22         heights.append(0)#默认最后补充一个0,方便统一处理
23         n = len(heights)
24         s = []
25         max_area = 0#最大面积
26         tp = 0#栈顶索引
27         area_with_top = 0#临时面积
28         i = 0
29         while i < n:
30             if len(s) == 0 or heights[s[-1]] <= heights[i]:
31                 s.append(i)#栈内记录的是高度递增的索引
32                 i += 1
33             else:#遇到了高度比当前栈顶元素低的元素时,
34                 tp = s.pop(-1)#清算栈内的元素的高度
35                 if len(s) == 0:
36                     area_with_top = heights[tp] * i#栈内没有元素,则宽度是i
37                 else:#高度是栈顶元素,宽度是i - 1 - 前一个栈顶元素的索引
38                     area_with_top = heights[tp] * (i - s[-1] - 1)
39                 max_area = max(max_area,area_with_top)#更新最大值
40         return max_area
41 
42     def resetHeight(self,matrix,height,idx):
43         for i in range(len(matrix[0])):
44             if matrix[idx][i] == '1':
45                 height[i] += 1
46             else:
47                 height[i] = 0

思路分析:本题以leetcode 84为基础,相当于计算一个柱状图中最大的面积。

如图上所示,对于数组[2,1,5,6,2,3]其最大面积是10。在此基础上,将本题转化为row次的柱状图计算:

按照行“递增”计算4次。

1、[1,0,1,0,0],最大面积是1

2、[1+1,0,1+1,1,1] => [2,0,2,1,1],最大面积是3

3、[1+1+1,1,1+1+1,1+1,1+1] => [3,1,3,2,2],最大面积是6

4、[1+1+1+1,0,0,1+1+1,0] => [4,0,0,3,0],最大面积是4

经过这4次循环,计算完毕。第3次得到的结果,是这个二维数组可构成的最大面积6。

 

posted on 2019-03-07 11:48  Sempron2800+  阅读(182)  评论(0编辑  收藏  举报