leetcode 84. Largest Rectangle in Histogram 最大直方图 + DP +stack

- 日理万妓 2022-06-08 02:26 218阅读 0赞

Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

这里写图片描述
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.

这里写图片描述
For example,
Given heights = [2,1,5,6,2,3],
return 10.

这道题和 leetcode 32. Longest Valid Parentheses 最长有效括号长度很类似,可以放到一起学习。

这道题最直接的方法就是暴力搜索了,从第一个方块开始,向前向后一直搜索到比它高度小的方块为止,然后更新最大面积,这种方法的时间复杂度是O(n^2)。

借助于stack这一数据结构,可以实现一个O(n)的算法,具体思路如下:stack中存储的是方块的下标索引号,如果当前方块的高度大于等于栈顶元素对应方块的高度,那么就将该方块的索引号进栈。否则(即当前方块高度更小时),则说明继续划分下去会产生镂空区域,因此我们将栈顶元素一次出栈,每次出栈时都计算一下以该栈顶元素为高度基准时,划分出的面积大小。

建议和leetcode 85. Maximal Rectangle 最大子矩阵 一起学习,这道题是对本体做的一个很不错的拓展,很值得学习

代码如下:

  1. import java.util.Stack;
  2. /*
  3. * stack中存储的是方块的下标索引号,如果当前方块的高度大于等于栈顶元素对应方块的高度,
  4. * 那么就将该方块的索引号进栈。否则(即当前方块高度更小时),则说明继续划分下去会产生镂空区域,
  5. * 因此我们将栈顶元素一次出栈,每次出栈时都计算一下以该栈顶元素为高度基准时,划分出的面积大小。
  6. * 这样这个算法复杂度就降低到了O(n),具体请看代码。
  7. * */
  8. public class Solution
  9. {
  10. public int largestRectangleArea(int[] height)
  11. {
  12. if(height==null || height.length<=0)
  13. return 0;
  14. int maxArea=0,i=0;
  15. Stack<Integer> stack=new Stack<>();
  16. while(i<height.length)
  17. {
  18. //要是可以保证升序序列就直接进栈
  19. if(stack.isEmpty() || height[stack.peek()] <= height[i])
  20. stack.push(i++);
  21. else
  22. {
  23. /*
  24. * 否者的话直接计算以height[pre]为高度的面积,为什么呢?
  25. * 因为假如pre之前有比height[pre]要小的元素,那么pre早就出栈了,
  26. * 所以可以计算以height[pre]为高度的面积,那么宽度是哪里呢?
  27. * 首先起点是stack的top+1,因为height[pre]要比现在的top的height要大,
  28. * 同时重点是i-1,因为height[pre]>height[i]
  29. * */
  30. int pre=stack.pop();
  31. int width=stack.isEmpty()?(i-1)-0+1 : (i-1)-(stack.peek()+1)+1;
  32. maxArea=Math.max(maxArea, width * height[pre]);
  33. }
  34. }
  35. //其实到了这里i就是height.length
  36. while(stack.isEmpty()==false)
  37. {
  38. int pre=stack.pop();
  39. int width=stack.isEmpty()?(height.length-1)-0+1 : (height.length-1)-(stack.peek()+1)+1;
  40. maxArea=Math.max(maxArea, width * height[pre]);
  41. }
  42. return maxArea;
  43. }
  44. }

下面是C++的做法,这道题很值得学习

代码如下:

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <stack>
  5. using namespace std;
  6. class Solution
  7. {
  8. public:
  9. int largestRectangleArea(vector<int>& hei)
  10. {
  11. if (hei.size() <= 0)
  12. return 0;
  13. stack<int> index;
  14. int i = 0, maxArea = -1;
  15. while (i < hei.size())
  16. {
  17. if (index.empty() || hei[i] >= hei[index.top()])
  18. index.push(i++);
  19. else
  20. {
  21. int pre = index.top();
  22. index.pop();
  23. int width = index.empty() ? (i - 1) - 0 + 1 : (i - 1) - (index.top()+1) + 1;
  24. maxArea = max(maxArea, width*hei[pre]);
  25. }
  26. }
  27. while (index.empty() == false)
  28. {
  29. int pre = index.top();
  30. index.pop();
  31. int width = index.empty() ? (hei.size() - 1) - 0 + 1 : (hei.size() - 1) - (index.top() + 1) + 1;
  32. maxArea = max(maxArea, width*hei[pre]);
  33. }
  34. return maxArea;
  35. }
  36. };

发表评论

表情:
评论列表 (有 0 条评论,218人围观)

还没有评论,来说两句吧...

相关阅读