寻找最小矩形

  1. 在看到题的时候,先看看数据的范围
    1. n <= 4:任何时间复杂度的算法都可以用
    2. n <= 1000: 需要考虑O(n^2) / O(n^2logn)的算法才可以
    3. n <= 50000:需要考虑O(nlogn) O(nlog^2n), O(n)的算法
  2. 首先想到蛮力算法
    1. 底是从lo到hi的,那么底为hi - lo + 1
    2. 高就是lo到hi之间最低的高度
    3. 因此我们枚举每一个底边,计算出高,并找到最大的面积
    4. 思路:枚举每一个底边,再在这个范围里面找到高
    5. 时间复杂度O(n^3)
  3. 具体代码(蛮力算法)
class Solution {
public:
    //蛮力算法
    int largestRectangleArea(vector<int>& heights) {
        int ans(0);
        for (int lo(0); lo < heights.size(); lo++) {
            for (int hi(lo); hi < heights.size(); hi++) {
                int width = hi - lo + 1;
                int height(50000);
                //Error1: 在寻找loca的时候忽略了lo == hi的情况
                for (int loca = lo; loca <= hi; loca++) {
                    height = min(height, heights[loca]);
                }
                ans = max(ans, width * (height));
            }
        }
        return ans;
    }
};
  1. 蛮力算法的一种改进
    1. 我们发现,在枚举底边的时候,就可以顺带把最低的高度求出来了,其实就是利用了最低高度在一定范围内的不变性
  2. 具体算法(蛮力算法的一种优化),时间复杂度O(n^2)
class Solution {
public:
    //蛮力算法的一种优化
    int largestRectangleArea(vector<int>& heights) {
        int ans(0);
        for (int lo(0); lo < heights.size(); lo++) {
            int height(50000);
            for (int hi(lo); hi < heights.size(); hi++) {
                int width = hi - lo + 1;
                height = min(height, heights[hi]);
                ans = max(ans, width * (height));
            }
        }
        return ans;
    }
};
  1. 我们或许可以使用栈这种数据结构进行优化,个人认为算法思路还是找卡点,因为栈是单增的,所以遍历的过程就是在找右卡点。
    1. 维护一个单调栈(栈底到栈顶高度单调上升)
    2. 根据下一个需要插入的列和当前栈顶位置高度的关系
      1. 弹出栈并更新答案
      2. 将该列压入栈
  2. 代码如下(单调栈解法)
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        if (heights.empty()) {
            return 0;
        } else {
            //完成哨兵的插入
            heights.insert(heights.begin(), 0);
            heights.insert(heights.end(), 0);
        }
        int ans(0);
        stack<int> Stack = stack<int>();

        //Error2:先将哨兵压入
        Stack.push(0);
        //Error3:a的范围应该是< heights.size() - 1
        for (int a(1); a <= heights.size() - 1; a++) {
            //当前元素比栈顶元素小的时候,进行答案的更新
            while (heights[a] < heights[Stack.top()]) {
                //Error4:栈里面的都是位置
                int height = heights[Stack.top()];
                Stack.pop();
                ans = max(ans, (a - Stack.top() - 1) * height);
            }
            Stack.push(a);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43414275/article/details/107723424