leetcode84 柱状图中最大的矩形
题目描述
暴力法
依次遍历所有可能的矩阵情况,选出最小面积的矩阵
分治法
- 首先选出最小元素,乘以数组长度得到面积area;
- 最小元素左侧最小面积area_left;
- 最小元素右侧最小面积area_right;
- 最小面积 = Math.max(area, area_left, area_right);
public class Solution {
public int largestRectangleArea(int[] nums){
return largestRectangleArea(nums, 0, nums.length);
}
private int largestRectangleArea(int[] nums, int i, int j){
if(i == j) return 0;
if(j - i == 1) return nums[i];
int min_index = getMinIndex(nums, i, j);
int res = (j - i) * nums[min_index];
int left = largestRectangleArea(nums, i, min_index);
int right = largestRectangleArea(nums, min_index + 1, j);
res = Math.max(Math.max(res, left), right);
return res;
}
private int getMinIndex(int[] nums, int i, int j){
int min = i;
for(int k = i; k < j; k ++){
min = nums[min] > nums[k] ? k : min;
}
return min;
}
}
使用栈
维护一个栈,首先将-1压入栈中,按照顺序依次将元素得下标压入栈中,知道找到当前元素nums[i] < nums[i -1] 即元素出现递减为止,然后一次将元素出战知道nums[i] >= nums[stack.peek()],这时的矩阵大小为nums[i] * (i - stack.peek() - 1),重复上述操作,找出最大面积。
public class Solution2 {
public int largestRectangleArea(int[] nums){
Stack<Integer> stack = new Stack<Integer>();
stack.push(-1);
int maxArea = 0;
for(int i = 0; i < nums.length; i ++){
if(stack.peek() != -1 && nums[i] > nums[stack.peek()])
stack.push(i);
else{
while(stack.peek() != -1 && nums[i] < nums[stack.peek()]){
int top = stack.pop();
maxArea = Math.max(maxArea, (i - stack.peek() - 1) * nums[top]);
}
stack.push(i);
}
}
while(stack.peek() != -1){
maxArea = Math.max(maxArea, nums[stack.pop()] * (nums.length - stack.peek() - 1));
}
return maxArea;
}
}