LeetCode简易题解--084,085

来源:互联网 发布:java图书销售管理系统 编辑:程序博客网 时间:2024/05/16 07:59

84

题目描述:给出一个数组,数组中每个元素依次表示一个直方图的高度,每一格的宽度都为1.找出这个直方图中最大矩阵的面积。

基本思路:使用一个栈。
从左至右扫描数组,将每一格的下标压入栈,并且保证栈中元素自底向上是升序排序的。
当一个下标要压入栈时,检查栈顶下标代表的元素是否大于等于当前下标的元素。
如果大于等于,这个时候就可以进行矩形面积的计算了:

  • 将栈顶元素出栈,直到栈为空或者栈顶下标的元素小于当前下标的元素。对每一个出栈的下标:
  • 计算这个栈顶下标与当前下标的距离(宽度),再乘以栈顶下标的元素(高度),就得到了矩阵的面积。
  • 判断计算得到的矩阵面积是否最大,用res变量保存最大矩阵面积。

如果小于,只需简单地将下标压入栈即可。

但是还有一个问题,可能下标遍历结束后,栈不为空,(极端情况考虑给定数组是升序排序的),此时有许多可能的矩阵面积没有被计算出来。解决这个问题的一个办法是:
在给定数组的末尾添加一个元素0,因为高度不可能小于0,遍历到最后的这个0的下标时,栈中所有的元素都会被出栈,所有的可能成为最大的矩阵面积都得到了计算。

最终代码如下:

class Solution {public:    int largestRectangleArea(vector<int>& heights) {        int n = heights.size();        if (n == 0) return 0;        int res = 0;        heights.push_back(0);        stack<int> index;        for (int i = 0; i <= n; ++i) {            while (!index.empty() && heights[index.top()] >= heights[i]) {                int t = index.top();                index.pop();                // 通过左边的下标来计算宽度。                int left_index = index.empty() ? -1 : index.top();                res = max(res, heights[t] * (i - left_index - 1));            }            index.push(i);        }        return res;    }};

85

题目描述:给出一个二维的0,1串的矩阵,找出只含有1的最大矩阵的面积。
例如:

1 0 1 0 0  1 0 1 1 1  1 1 1 1 1  1 0 0 1 0  

答案为6.

基本思路:
将每一行以及这一行之上的矩阵部分看成一个直方图,每一列从下往上,遇到1表示有高度,遇到0就表示没有高度。
例如:

0 0 1 0 0  0 1 1 1 0   1 1 1 1 1  

这不就是一个中轴对称的直方图吗?
将每一行以及上面部分视为直方图,然后调用上面说到的第84题中的处理函数就能得到这一部分的最大矩阵面积。
遍历每一行,就得到了总体的最大矩阵面积。

代码如下:

class Solution {public:    int maximalRectangle(vector<vector<char>>& matrix) {        int m = matrix.size();        if (m == 0) return 0;        int n = matrix[0].size();        if (n == 0) return 0;        vector<int> height(n, 0);        int res = 0;        for (int i = 0; i < m; ++i) {            for (int j = 0; j < n; ++j) {                if (matrix[i][j] == 48) height[j] = 0;                else height[j] += 1;            }            int tmp = largestRectangleArea(height);            if (tmp > res) res = tmp;        }        return res;    }    // 与84相比,参数由引用传参变成了赋值传参,因为下面函数会修改传入的参数。    int largestRectangleArea(vector<int> heights) {        int n = heights.size();        if (n == 0) return 0;        int res = 0;        heights.push_back(0);        stack<int> index;        for (int i = 0; i <= n; ++i) {            while (!index.empty() && heights[index.top()] >= heights[i]) {                int t = index.top();                index.pop();                int left_index = index.empty() ? -1 : index.top();                res = max(res, heights[t] * (i - left_index - 1));            }            index.push(i);        }        return res;    }};
原创粉丝点击