Leetcode_栈(4)84.柱状图中的最大矩形+85.最大矩形

目录

84.柱状图中的最大矩形

85.最大矩形


84.柱状图中的最大矩形

方法1.暴力 O(n^3)

public class Solution {
   public int largestRectangleArea(int[] heights) {
       int maxarea = 0;
       for (int i = 0; i < heights.length; i++) {
           for (int j = i; j < heights.length; j++) {
               int minheight = Integer.MAX_VALUE;
               for (int k = i; k <= j; k++)
                   minheight = Math.min(minheight, heights[k]);
               maxarea = Math.max(maxarea, minheight * (j - i + 1));
           }
       }
       return maxarea;
   }
}

暴力优化O(n^2)

public class Solution {
   public int largestRectangleArea(int[] heights) {
       int maxarea = 0;
       for (int i = 0; i < heights.length; i++) {
           int minheight = Integer.MAX_VALUE;
           for (int j = i; j < heights.length; j++) {
               minheight = Math.min(minheight, heights[j]);
               maxarea = Math.max(maxarea, minheight * (j - i + 1));
           }
       }
       return maxarea;
   }
}

方法2.分治

  1. 确定了最矮柱子以后,矩形的宽尽可能往两边延伸。

  2. 在最矮柱子左边的最大面积矩形(子问题)。

  3. 在最矮柱子右边的最大面积矩形(子问题)。

public class Solution {
    public int calculateArea(int[] heights, int start, int end) {
        if (start > end)
            return 0;
        int minindex = start;
        for (int i = start; i <= end; i++)
            if (heights[minindex] > heights[i])
                minindex = i;
        return Math.max(heights[minindex] * (end - start + 1), Math.max(calculateArea(heights, start, minindex - 1), calculateArea(heights, minindex + 1, end)));
    }
    public int largestRectangleArea(int[] heights) {
        return calculateArea(heights, 0, heights.length - 1);
    }
}

方法3.单调栈

  • 时间复杂度:O(n)  n 个数字每个会被压栈弹栈各一次。

  • 空间复杂度: O(n)  用来存放栈中元素。

public class Solution {
    public int largestRectangleArea(int[] heights) {
        Stack < Integer > stack = new Stack < > ();
        stack.push(-1);
        int maxarea = 0;
        for (int i = 0; i < heights.length; ++i) {
            while (stack.peek() != -1 && heights[stack.peek()] >= heights[i])
                maxarea = Math.max(maxarea, heights[stack.pop()] * (i - stack.peek() - 1));
            stack.push(i);
        }
        while (stack.peek() != -1)
            maxarea = Math.max(maxarea, heights[stack.pop()] * (heights.length - stack.peek() -1));
        return maxarea;
    }
}

85.最大矩形

方法1.单调栈

  • 时间复杂度 O(MN)
  • 空间复杂度 O(M)

                             image.png

class Solution {
public:
   
    int maxArea(vector<int>& matrix) {
        stack<int> s;
        s.push(-1);
        int max_area = 0, height, width;
        for(int i = 0; i < matrix.size(); ++i) {
            while(s.top() != -1 &&  matrix[s.top()]>=matrix[i]) {
                height = matrix[s.top()];
                s.pop();
                width = i - s.top() - 1;
                max_area = max(max_area, height*width);
            }
            s.push(i);
        }
        while(s.top() != -1) {
            height = matrix[s.top()];
            s.pop();
            width = matrix.size() - s.top() - 1;
            max_area = max(max_area, height*width);
        }
        return max_area;
    }

    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.size() == 0) return 0;
        int size = matrix[0].size(), max_area = 0;
        vector<int>dp(size, 0);
        for(int i = 0; i < matrix.size(); ++i) {
            for(int j = 0; j < size; ++j) {
                //逐行更新dp数组,dp[j]代表第j列的柱子高度
                //当matrix[i][j] == '0' ,dp[j] = 0,这很重要,仔细想一下
                dp[j] = matrix[i][j] == '1' ? dp[j] + 1 : 0;
            }
            //逐行更新此时连续柱体形成的矩形面积
            max_area = max(max_area, maxArea(dp));
        }
        return max_area;
    }
  
};

方法2.dp

  • 时间复杂度 : O(NM)O(NM)。每次对于N的迭代我们会对M迭代常数次。

  • 空间复杂度 : O(M)O(M), M 是我们保留的额外数组的长度。

class Solution {

    public int maximalRectangle(char[][] matrix) {
        if(matrix.length == 0) return 0;
        int m = matrix.length;
        int n = matrix[0].length;

        int[] left = new int[n]; // initialize left as the leftmost boundary possible
        int[] right = new int[n];
        int[] height = new int[n];

        Arrays.fill(right, n); // initialize right as the rightmost boundary possible

        int maxarea = 0;
        for(int i = 0; i < m; i++) {
            int cur_left = 0, cur_right = n;
            // update height
            for(int j = 0; j < n; j++) {
                if(matrix[i][j] == '1') height[j]++;
                else height[j] = 0;
            }
            // update left
            for(int j=0; j<n; j++) {
                if(matrix[i][j]=='1') left[j]=Math.max(left[j],cur_left);
                else {left[j]=0; cur_left=j+1;}
            }
            // update right
            for(int j = n - 1; j >= 0; j--) {
                if(matrix[i][j] == '1') right[j] = Math.min(right[j], cur_right);
                else {right[j] = n; cur_right = j;}    
            }
            // update area
            for(int j = 0; j < n; j++) {
                maxarea = Math.max(maxarea, (right[j] - left[j]) * height[j]);
            }
        return maxarea;
    }
}
发布了88 篇原创文章 · 获赞 77 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43107805/article/details/104943919
今日推荐