码迷,mamicode.com
首页 > 其他好文 > 详细

【leetcode #84 & #85】Maximal Rectangle

时间:2016-08-10 13:59:36      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

很简单,很有趣的一类题,好像在CF上出现过。。不太记得了

题意是给你N个1*N的矩形排列,要你框一个框,使得框出来的面积最大,就像这样:

技术分享技术分享

也就是说,一个高度,他要向后扩展的条件是,它后面的所有矩形高度不小于它。

考虑一种最简单的情况,若整个矩形阵是升序的,那么显然 ans = max(ans,h[i] * (n - i));

若序列不是升序的,那么对于任意位置的矩形,考虑仅向右拓展的情况,它前面的矩形只有小于它的高度的部分,以及它后面的矩形只有大于等于它,才能将这个矩形完整包括在内,如上右图的(5,6),对于5来说,6只有5的部分才有用。那么我们只要把整个序列强行变成升序的就好了。

这里可以利用栈来实现,当h[i] >= height.top()时,压栈

当h[i] < height.top()时,弹栈,直到满足h[i] >= height.top()时,压栈,再将与弹栈数量相同的h[i]压栈

首先可以肯定,我们构造的栈一定是升序的,那么如上图,当我们构造到

(1,1,5,6)(第一个1因为上述步骤压入),当2来到时,我们需要把(5,6)弹出

在弹出的过程中万一有最优解呢?

所以我们需要记录弹出时能够构造的最大矩形,显然,也应该是ans = max(ans,height.top()*cnt),这里的cnt指弹栈数量

比如6弹出,应该记录1*6,然后5弹出,cnt++,记录2*5

当height.top()==1时,将3个2压栈,至此,(1,1,6,5)->(1,1,2,2,2)

所以整个流程是这样的:

2来到->(2)

-> 1来到 -> 2弹出,将两个1压入 -> (1,1)  //记录了2*1

-> 5来到 -> (1,1,5)

-> 6来到 -> (1,1,5,6)

-> 2来到 -> 6,5弹栈 -> 3个2压入 ->(1,1,2,2,2)  //记录了6*1 5*2

-> 3来到 -> (1,1,2,2,2,3)

再按推出的升序的ans公式扫一遍即可~

我觉得单调栈也能做,反正就是利用单调性做文章就行了

code:

技术分享
 1 class Solution {
 2 public:
 3     int largestRectangleArea(vector<int>& heights) {
 4         stack<int>hei;
 5     int ans = 0;
 6     for (int i = 0; i < heights.size(); ++i) {
 7         if (hei.empty() || hei.top() <= heights[i]) {
 8             hei.push(heights[i]);
 9         }
10         else {
11             int len = 1;
12             while (!hei.empty() && hei.top() > heights[i]) {
13                 ans = max(ans, len*hei.top());
14                 hei.pop();
15                 len++;
16             }
17             while(len--) hei.push(heights[i]);
18         }
19     }
20     int len = 1;
21     while (!hei.empty()) {
22         ans = max(ans, hei.top()*len);
23         //cout << hei.top() << endl;
24         hei.pop();
25         len++;
26     }
27     return ans;
28     }
29 };
View Code

然后#85 给你一个二维矩阵,要框出其中最大的全1矩形

只要知道从上往下看,假如有0就代表断了

简单来说就是如果当前这一行的这个位置是0,那么height[i]=0,不是0,就height[i]++;

然后用上面的代码跑N次就行啦

code:

技术分享
 1 class Solution {
 2 public:
 3     int maximalRectangle(vector<vector<char>>& matrix) {
 4        vector<int>height;
 5        int ans = 0;
 6        for(int i = 0; i < matrix.size(); ++i){
 7             for(int j = 0; j < matrix[i].size(); ++j){
 8                 if(i == 0){
 9                     if(matrix[i][j] == 0) height.push_back(0);
10                     else height.push_back(1);
11                 }
12                 else{
13                     if(matrix[i][j] == 0) height[j] = 0;
14                     else height[j] += 1;
15                 }
16             }
17             ans = max(ans,solve(height));
18        }
19        return ans;
20     }
21 private:
22     int solve(vector<int> heights) {
23     stack<int>hei;
24     int ans = 0;
25     for (int i = 0; i < heights.size(); ++i) {
26         if (hei.empty() || hei.top() <= heights[i]) {
27             hei.push(heights[i]);
28         }
29         else {
30             int len = 1;
31             while (!hei.empty() && hei.top() > heights[i]) {
32                 ans = max(ans, len*hei.top());
33                 hei.pop();
34                 len++;
35             }
36             while (len--) hei.push(heights[i]);
37         }
38     }
39     int len = 1;
40     while (!hei.empty()) {
41         ans = max(ans, hei.top()*len);
42         //cout << hei.top() << endl;
43         hei.pop();
44         len++;
45     }
46     return ans;
47 }
48 };
View Code

其实和扫描线有点类似?

 

【leetcode #84 & #85】Maximal Rectangle

标签:

原文地址:http://www.cnblogs.com/mashiroG/p/5756310.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!