【leetcode #84 & #85】Maximal Rectangle

很简单,很有趣的一类题,好像在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 };

然后#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 };

其实和扫描线有点类似?

时间: 2024-11-06 07:20:35

【leetcode #84 & #85】Maximal Rectangle的相关文章

【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. 题解,很巧妙的一道题,对于一个0-1矩阵,它的每一行及以上都可以看作一个直方图(如下图所示),利用Largest Rectangle in Histogram的方法,可以在O(n)的时间搜索出这一行及以上的直方图中面积最大的矩形,对矩阵的每一行依次做这个操作,就可

【Leetcode长征系列】Letter Combinations of a Phone Number

原题: Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Input:Digit string "23" Output: ["ad", "ae"

【Leetcode长征系列】Merge k Sorted Lists

原题: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:两条两条地合并.时间复杂度为O(n),n为所有链表节点和. 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) :

【leetcode 字符串处理】Compare Version Numbers

[leetcode 字符串处理]Compare Version Numbers @author:wepon @blog:http://blog.csdn.net/u012162613 1.题目 Compare two version numbers version1 and version1. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. You may assume

【Leetcode长征系列】Construct Binary Tree from Inorder and Postorder Traversal

原题: Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 思路:和上一题一样,后续我们可以通过最后一个值得到根的值,同样可以通过定位根的值得到左右子树的子集,递归求解即可. 代码: /** * Definition for binary tree * struct Tre

【Leetcode长征系列】Single Number II

原题: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 思路: 用一个32位的数组存每一位bit值之后.得到答案后每一位除

【Leetcode长征系列】Pow(x, n)

原题: Implement pow(x, n). 思路:递归计算pow. class Solution { public: double pow(double x, int n) { long long int mid = n/2; int d = n%2; if(n==0) return 1; if(n==1) return x; if(d==1) return pow(x, (n/2)+1) * pow(x, n/2); else return pow(x, n/2) * pow(x, n/

【Leetcode长征系列】Sqrt(x)

原题: Implement int sqrt(int x). Compute and return the square root of x. ==============================以下为引用==================================== 牛顿迭代法 为了方便理解,就先以本题为例: 计算x2 = n的解,令f(x)=x2-n,相当于求解f(x)=0的解,如左图所示. 首先取x0,如果x0不是解,做一个经过(x0,f(x0))这个点的切线,与x轴的交

【Leetcode长征系列】Balanced Binary Tree

原题: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees ofevery node never differ by more than 1. 思路:递归判断左右子树是否为BST. 代码: /** * Def