目录
- 【力扣】84. 柱状图中最大的矩形
- 题解
- 暴力求解
- 双指针
- 单调栈
【力扣】84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
提示:
1 <= heights.length <= 1 0 5 10^5 105
0 <= heights[i] <= 1 0 4 10^4 104
题解
暴力求解
public static int largestRectangleArea(int[] heights) {int sum = 0;for (int i = 0; i < heights.length; i++) {int left = i;int right = i;//找当前遍历元素之前第一个比它小的元素while (left >= 0) {if (heights[left] < heights[i]) {break;}left--;}//找当前遍历元素之后第一个比它小的元素while (right < heights.length) {if (heights[right] < heights[i]) {break;}right++;}int w = right - left - 1;int h = heights[i];sum = Math.max(sum, w * h);}return sum;
}
双指针
public class Solution {public static int largestRectangleArea(int[] heights) {int[] minLeftIndex = new int[heights.length];int[] minRightIndex = new int[heights.length];// 记录左边第一个小于该柱子的下标minLeftIndex[0] = -1;for (int i = 1; i < heights.length; i++) {int t = i - 1;// 这里不是用if,而是不断向右寻找的过程while (t >= 0 && heights[t] >= heights[i]) {t = minLeftIndex[t];}minLeftIndex[i] = t;}// 记录每个柱子右边第一个小于该柱子的下标minRightIndex[heights.length - 1] = heights.length;for (int i = heights.length - 2; i >= 0; i--) {int t = i + 1;while (t < heights.length && heights[t] >= heights[i]) {t = minRightIndex[t];}minRightIndex[i] = t;}/*for (int a : minLeftIndex) {System.out.println(a);}System.out.println("______________________________");for (int a : minRightIndex) {System.out.println(a);}*/// 求和int result = 0;for (int i = 0; i < heights.length; i++) {int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);result = Math.max(sum, result);}return result;}public static void main(String[] args) {int[] heights = {2, 4, 2};System.out.println(largestRectangleArea(heights));}
}
单调栈
注意:单调栈是递减的
class Solution {int largestRectangleArea(int[] heights) {Stack<Integer> st = new Stack<Integer>();// 数组扩容,在头和尾各加入一个元素,防止只递增或者只递减的数组int [] newHeights = new int[heights.length + 2];newHeights[0] = 0;newHeights[newHeights.length - 1] = 0;for (int index = 0; index < heights.length; index++){newHeights[index + 1] = heights[index];}heights = newHeights;st.push(0);int result = 0;// 第一个元素已经入栈,从下标1开始for (int i = 1; i < heights.length; i++) {// 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下标if (heights[i] > heights[st.peek()]) {st.push(i);} else if (heights[i] == heights[st.peek()]) {st.pop(); // 这个可以加,可以不加,效果一样,思路不同st.push(i);} else {while (heights[i] < heights[st.peek()]) { // 注意是whileint mid = st.peek();st.pop();int left = st.peek();int right = i;int w = right - left - 1;int h = heights[mid];result = Math.max(result, w * h);}st.push(i);}}return result;}
}