zoukankan      html  css  js  c++  java
  • [LeetCode] Maximal Rectangle

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

    思路:

    动态规划:

    f[i][j] 表示在第i行中以(i,j)点结束点的前面有多少个连续的1,就是用f[i][j]来记录i行以j列为结尾,往前连续的1的个数。

    然后用O(n^3)的循环来找以(i, j)为右下角的矩形最大的矩形的面积。

    例如数组为

    0  0  1

    1  1  1

    0  1  1

    那么f数组为

    0  0  1

    1  2  3

    0  1  2

    在计算f[i][j]时使用的是一维动态规划

    计算(i, j)为右下角的矩形最大的矩形的面积时,就是就去第0行到i行中以j结尾矩形的最大值,就是之前求过的 Largest Rectangle in Histogram

    相当于是每一列,求一次Largest Rectangle in Histogram,然后求其所有列的最大值。。

    方法一: O(n^3)

    转载 http://www.cnblogs.com/remlostime/archive/2012/11/12/2766566.html

     1 class Solution {
     2     private:
     3         int f[1000][1000];
     4     public:
     5         int maximalRectangle(vector<vector<char> > &matrix) {
     6             // Start typing your C/C++ solution below
     7             // DO NOT write int main() function
     8             for(int i = 0; i < matrix.size(); i++)
     9                 f[i][0] = matrix[i][0] == '1' ? 1 : 0;
    10 
    11             for(int i = 0; i < matrix.size(); i++)
    12                 for(int j = 1; j < matrix[i].size(); j++)
    13                     f[i][j] = matrix[i][j] == '1' ? f[i][j-1] + 1 : 0;
    14 
    15             int ret = 0;
    16             for(int i = 0; i < matrix.size(); i++)
    17             {
    18                 for(int j = 0; j < matrix[i].size(); j++)
    19                 {
    20                     int wid = INT_MAX;
    21                     for(int k = i; k >=0; k--)
    22                     {
    23                         if(f[i][j] == 0)
    24                             break;
    25                         wid = min(wid, f[k][j]);
    26                         ret = max(ret, wid* (i-k +1));
    27                     }
    28 
    29                 }
    30             }
    31             return ret;
    32 
    33         }
    34 };

     方法二,基于largestRectangleArea

    将matrxi看出n行,求出每行的高度,然后调用largestRectangleArea

    求解每行的高度的时候,使用的动态规划方法和方法一类似,

    f[i][j]表示第i列中以(i,j)为结束连续1的个数

    重点是

    if(matrix[i][j] == '1')
    f[i][j] = f[i-1][j] + 1;
    else
    f[i][j] = 0;

     共n行,每行调用largestRectangleArea的复杂度为O(n),所以是O(n^2),空间复杂度由于有矩阵f的存在,也是O(n^2)

     1 class Solution
     2 {
     3     public:
     4         int largestRectangleArea(vector<int> &height) {
     5 
     6             //add 0 to the end
     7             height.push_back(0);
     8 
     9             int size = height.size(); //this new_size is 1 + old_size
    10             stack<int> st;
    11 
    12             int max_area = 0;
    13 
    14 
    15 
    16             for(int i = 0; i< size; )
    17             {
    18                 if(st.empty() || height[i] > height[st.top()])
    19                 {
    20                     st.push(i);
    21                     i++;
    22                 }
    23                 else
    24                 {
    25                     //st must be not empty here
    26                     // i can't ++; handle many times perhaps
    27 
    28                     int idx = st.top();
    29                     st.pop();
    30 
    31                     int area;
    32 
    33                     if(st.empty())
    34                     {
    35                         area = height[idx] * i;
    36                     }
    37                     else
    38                     {
    39                         area = height[idx] * (i-st.top()-1);
    40                     }
    41 
    42                     max_area = max(max_area, area);
    43 
    44                 }
    45             }
    46             return max_area;
    47         }
    48 
    49         int maximalRectangle(vector<vector<char> > &matrix)
    50         {
    51             if(matrix.empty() || matrix[0].empty())
    52                 return 0;
    53             size_t row = matrix.size();
    54             size_t col = matrix[0].size();
    55 
    56             //construct matrix f;
    57             vector<vector<int> > f(row);
    58             vector<int> array;
    59             array.resize(col, 0);
    60 
    61             for(int i = 0; i < row; i++)
    62                 f[i] = array;
    63 
    64             // initial f[0], the first row
    65             for(int j = 0; j < col; j++)
    66             {
    67                 if(matrix[0][j] == '1')
    68                     f[0][j] = 1;
    69                 else
    70                     f[0][j] = 0;
    71             }
    72 
    73             for(int i = 1; i < row; i++)
    74             {
    75                 for(int j = 0; j < col; j++)
    76                 {
    77                     if(matrix[i][j] == '1')
    78                         f[i][j] = f[i-1][j] + 1;
    79                     else
    80                         f[i][j] = 0;
    81                 }
    82             }
    83 
    84             int ret = 0;
    85             for(int i = 0; i < row; i++)
    86             {
    87 
    88                 ret = max(ret, largestRectangleArea(f[i]));
    89             }
    90 
    91             return ret;
    92 
    93         }
    94 } ;

     适当的优化:

      由于f[i][j] = f[i-1][j] + 1;的关系,二期在计算第i行时,第i-1行的数据有用,再之前的数据就没有了,所以我么可以不用保留整个col*row的矩阵,而只用一个数组就够了

      空间复杂度O(n),时间复杂度还是O(n^2)

     1 class Solution
     2 {
     3     public:
     4         int largestRectangleArea(vector<int> &height) {
     5 
     6             //add 0 to the end
     7             height.push_back(0);
     8 
     9             int size = height.size(); //this new_size is 1 + old_size
    10             stack<int> st;
    11 
    12             int max_area = 0;
    13 
    14 
    15 
    16             for(int i = 0; i< size; )
    17             {
    18                 if(st.empty() || height[i] > height[st.top()])
    19                 {
    20                     st.push(i);
    21                     i++;
    22                 }
    23                 else
    24                 {
    25                     //st must be not empty here
    26                     // i can't ++; handle many times perhaps
    27 
    28                     int idx = st.top();
    29                     st.pop();
    30 
    31                     int area;
    32 
    33                     if(st.empty())
    34                     {
    35                         area = height[idx] * i;
    36                     }
    37                     else
    38                     {
    39                         area = height[idx] * (i-st.top()-1);
    40                     }
    41 
    42                     max_area = max(max_area, area);
    43 
    44                 }
    45             }
    46             return max_area;
    47         }
    48 
    49         int maximalRectangle(vector<vector<char> > &matrix)
    50         {
    51             if(matrix.empty() || matrix[0].empty())
    52                 return 0;
    53             size_t row = matrix.size();
    54             size_t col = matrix[0].size();
    55 
    56             vector<int> f;
    57             f.resize(col, 0);
    58 
    59             int ret = 0;
    60             for(int i = 0; i < row; i++)
    61             {
    62                 // update f
    63                 for(int j = 0; j < col; j++)
    64                 {
    65                     // the first row 
    66                     if(i == 0)
    67                     {
    68                         if(matrix[0][j] == '1')
    69                             f[j] = 1;
    70                         else
    71                             f[j] = 0;
    72                     }
    73                     // other rows
    74                     else
    75                     {
    76                         if(matrix[i][j] == '1')
    77                             f[j] = f[j] + 1;
    78                         else
    79                             f[j] = 0;
    80                     }
    81                 }
    82 
    83                 ret = max(ret, largestRectangleArea(f));
    84             }
    85 
    86             return ret;
    87 
    88         }
    89 } ;
  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/diegodu/p/3823868.html
Copyright © 2011-2022 走看看