85.Maximal Rectangle---dp

題目連接:https://leetcode.com/problems/maximal-rectangle/description/數組

題目大意:給出一個二維矩陣,計算最大的矩形面積(矩形由1組成)。例子以下:ide

法一:將每一行的數據都當作是一個直方圖,而每一個直方圖的高度都是由上一行獲得的,例如,上述例子中,從上到下直方圖的高度依次是:[1,0,1,0,0],[2,0,2,1,1],[3,1,3,2,2],[4,0,0,3,0]。也就是噹噹前值是0時,則高度是0;當前值是1時,則高度=上一行的高度+1。這樣,對於每一行的直方圖能夠利用84題的求解辦法,這裏多的步驟就是將每一行數據轉換成直方圖,而後再根據每一個直方圖求解最大矩形面積。代碼以下(耗時49ms):spa

 1     public int maximalRectangle(char[][] matrix) {
 2         if(matrix.length == 0) {
 3             return 0;
 4         }
 5         Stack<Integer> s = new Stack<Integer>();
 6         int h[] = new int[matrix[0].length];
 7         int res = 0;
 8         for(int i = 0; i < matrix.length; i++) {
 9             for(int j = 0; j < matrix[0].length; j++) {
10                 //轉換成直方圖
11                 h[j] = (matrix[i][j] == '1') ? (h[j] + 1) : 0;
12                 //根據每一個直方圖,計算其最大矩形面積,利用84題的方法
13                 while(!s.isEmpty() && h[s.peek()] >= h[j]) {
14                     int cur = s.pop();
15                     res = Math.max(res, h[cur] * (s.isEmpty() ? j : (j - s.peek() - 1)));
16                 }
17                 s.push(j);
18             }
19             while(!s.isEmpty()) {
20                 int cur = s.pop();
21                 res = Math.max(res, h[cur] * (s.isEmpty() ? h.length : (h.length - s.peek() - 1)));
22             }
23         }
24         return res;
25     }
View Code

法二:dp思想,依舊將每一行的數據當作一個直方圖,而後轉換成直方圖,用left[]數組表示左邊界1的位置,用right[]數組表示右邊界1的位置。代碼以下(耗時13ms):code

 1     public int maximalRectangle(char[][] matrix) {
 2         if(matrix.length == 0) {
 3             return 0;
 4         }
 5         int h[] = new int[matrix[0].length];
 6         int left[] = new int[matrix[0].length], right[] = new int[matrix[0].length];
 7         //初始化right數組 爲matrix[0].length
 8         for(int i = 0; i < matrix[0].length; i++) {
 9             right[i] = matrix[0].length;
10         }
11         int res = 0;
12         for(int i = 0; i < matrix.length; i++) {
13             int cur_left = 0, cur_right = matrix[0].length;
14             //轉換成直方圖
15             for(int j = 0; j < matrix[0].length; j++) {
16                 h[j] = (matrix[i][j] == '1') ? (h[j] + 1) : 0;
17             }
18             //計算左邊1的下標
19             for(int j = 0; j < matrix[0].length; j++) {
20                 if(matrix[i][j] == '1') {
21                     left[j] = Math.max(left[j], cur_left);
22                 }
23                 else {
24                     left[j] = 0;
25                     cur_left = j + 1;
26                 }
27             }
28             //計算右邊1的下標
29             for(int j = matrix[0].length - 1; j >= 0; j--) {
30                 if(matrix[i][j] == '1') {
31                     right[j] = Math.min(right[j], cur_right);
32                 }
33                 else {
34                     right[j] = matrix[0].length;
35                     cur_right = j;
36                 }
37             }
38             //計算矩形面積
39             for(int j = 0; j < matrix[0].length; j++) {
40                 res = Math.max(res, (right[j] - left[j]) * h[j]);
41             }
42         }
43         return res;
44     }
View Code
相關文章
相關標籤/搜索