zoukankan      html  css  js  c++  java
  • 85.Maximal Rectangle---dp

    题目链接:https://leetcode.com/problems/maximal-rectangle/description/

    题目大意:给出一个二维矩阵,计算最大的矩形面积(矩形由1组成)。例子如下:

    法一:将每一行的数据都看成是一个直方图,而每个直方图的高度都是由上一行得到的,例如,上述例子中,从上到下直方图的高度依次是:[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):

     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):

     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
  • 相关阅读:
    第二次作业循环语句
    c语言01次作业分支,顺序结构
    PAT 1027. Colors in Mars
    PAT 1026 Table Tennis
    PAT 1035 Password
    PAT 1038. Recover the Smallest Number
    PAT 1028 List Sorting (25)
    PAT 1041 Be Unique (20)
    PAT 1025 PAT Ranking
    1037. Magic Coupon
  • 原文地址:https://www.cnblogs.com/cing/p/8504995.html
Copyright © 2011-2022 走看看