最大的矩形面積 Maximal Rectangle
阿新 • • 發佈:2018-09-15
htm public length for angle col ram com pub
2018-09-15 10:23:44
一、Largest Rectangle in Histogram
在求解最大的矩形面積之前,我們先討論一條最大直方圖面積的問題。
問題描述:
問題求解:
解法一、樸素解法,O(n ^ 2)。
解決的思路就是遍歷一遍,如果當前的數比後一個數要小,那麽當前的額數字肯定不可能是最大面積的右邊界,遍歷下一個數;
如果當前數比後一個大,那麽假設當前的為右邊界,向左進行遍歷,計算面積最大值。
public int largestRectangleArea(int[] heights) { if (heights.length == 0) return 0; int res = 0; for (int i = 0; i < heights.length; i++) { if (i == heights.length - 1 || heights[i] > heights[i + 1]) { int minHeight = heights[i]; for (int j = i; j >= 0; j--) { minHeight = Math.min(heights[j], minHeight); res = Math.max(res, minHeight * (i - j + 1)); } } } return res; }
解法二、使用堆棧,時間復雜度O(n)。
核心的思路是,尋找每個直方圖的左邊和右邊第一個比他小的位置,然後計算其能達到的面積最大值,最後取max即可。
public int largestRectangleArea(int[] heights) { if (heights.length == 0) return 0; int res = 0; Stack<Integer> stack = new Stack<>(); int idx, leftMost, rightMost; for (int i = 0; i < heights.length; i++) { if (stack.isEmpty() || heights[i] >= heights[stack.peek()]) stack.push(i); else { rightMost = i; idx = stack.pop(); while (!stack.isEmpty() && heights[stack.peek()] == heights[idx]) idx = stack.pop(); leftMost = stack.isEmpty() ? -1 : stack.peek(); res = Math.max(res, heights[idx] * (rightMost - leftMost - 1)); i--; } } rightMost = stack.isEmpty() ? 0 :stack.peek() + 1; while (!stack.isEmpty()) { idx = stack.pop(); leftMost = stack.isEmpty() ? -1 : stack.peek(); res = Math.max(res, heights[idx] * (rightMost - leftMost - 1)); } return res; }
二、Maximal Rectangle
問題描述:
問題求解:
有個上一個問題的鋪墊,這個問題就很好解決了,針對每一行,可以先求出其高度,然後再對每一行求最大最方圖的面積,取max即可。
public int maximalRectangle(char[][] matrix) { if (matrix.length == 0 || matrix[0].length == 0) return 0; int m = matrix.length; int n = matrix[0].length; int[][] height = new int[m][n]; int res = 0; for (int i = 0; i < n; i++) height[0][i] = matrix[0][i] - ‘0‘; for (int i = 1; i < m; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] == ‘0‘) height[i][j] = 0; else height[i][j] = 1 + height[i - 1][j]; } } for (int i = 0; i < m; i++) { res = Math.max(res, fastHelper(height[i])); } return res; } private int helper(int[] nums) { int res = 0; for (int i = 0; i < nums.length; i++) { if (i == nums.length - 1 || nums[i] > nums[i + 1]) { int minHeight = nums[i]; for (int j = i; j >= 0; j--) { minHeight = Math.min(minHeight, nums[j]); res = Math.max(res, (i - j + 1) * minHeight); } } } return res; } private int fastHelper(int[] nums) { int res = 0; int idx, leftMost, rightMost; Stack<Integer> stack = new Stack<>(); for (int i = 0; i < nums.length; i++) { if (stack.isEmpty() || nums[i] >= nums[stack.peek()]) stack.push(i); else { rightMost = i; idx = stack.pop(); while (!stack.isEmpty() && nums[idx] == nums[stack.peek()]) idx= stack.pop(); leftMost = stack.isEmpty() ? -1 : stack.peek(); res = Math.max(res, nums[idx] * (rightMost - leftMost - 1)); i--; } } rightMost = stack.isEmpty() ? 0 : stack.peek() + 1; while (!stack.isEmpty()) { idx = stack.pop(); while (!stack.isEmpty() && nums[idx] == nums[stack.peek()]) idx= stack.pop(); leftMost = stack.isEmpty() ? -1 : stack.peek(); res = Math.max(res, nums[idx] * (rightMost - leftMost - 1)); } return res; }
最大的矩形面積 Maximal Rectangle