题目描述
解题思路
具体参照:carl的题解
主要和接雨水不同的是求的是两边小于中间。
双指针(超时)
/*** 双指针法(超时)** @param heights* @return*/public int largestRectangleArea(int[] heights) {int maxSize = 0;for (int i = 0; i < heights.length; i++) {int leftIndex = i;int rightIndex = i;// 找到小于i的高度for (; leftIndex >= 0; leftIndex--) {if (heights[leftIndex] < heights[i]) break;}for (; rightIndex < heights.length; rightIndex++) {if (heights[rightIndex] < heights[i]) break;}int high = heights[i];int width = rightIndex - leftIndex - 1;maxSize = Math.max(maxSize, high * width);}return maxSize;}
动态规划
/*** 动态规划** @param heights* @return*/public int largestRectangleArea(int[] heights) {int[] minLeftIndex = new int[heights.length];int[] minRightIndex = new int[heights.length];int maxSize = 0;// 记录每个柱子 左边第一个小于该柱子的下标minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环for (int i = 1; i < heights.length; i++) {int t = i - 1;// 这里不是用if,而是不断向左寻找的过程while (t >= 0 && heights[t] >= heights[i])t = minLeftIndex[t]; // while一直循环找到左边第一个小于该柱子的下标minLeftIndex[i] = t;}minRightIndex[heights.length - 1] = heights.length;for (int i = heights.length - 2; i >= 0; i--) {int t = i + 1;// 这里不是用if,而是不断向左寻找的过程while (t < heights.length && heights[t] >= heights[i])t = minRightIndex[t]; // 记录每个柱子 右边第一个小于该柱子的下标minRightIndex[i] = t;}// 求和for (int i = 0; i < heights.length; i++) {int size = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);if (size > maxSize) maxSize = size;}return maxSize;}
⭐单调栈
public int largestRectangleArea(int[] heights) {// 数组扩容,在头尾各加一个元素int[] array = new int[heights.length + 2];array[0] = 0;array[heights.length + 1] = 0;for (int i = 0; i < heights.length; i++) {array[i + 1] = heights[i];}Stack<Integer> stack = new Stack<>();stack.push(0); // 栈顶到栈底,从大到小int maxSize = 0;heights = array; // 需要在头尾各加一个0,来保证大小为2或者1时特殊情况,和都是相同的数字也是特殊情况for (int i = 1; i < heights.length; i++) {if (heights[stack.peek()] < heights[i]) {stack.push(i);} else if (heights[stack.peek()] == heights[i]) {stack.pop();stack.push(i);} else {while (heights[stack.peek()] > heights[i]) {Integer mid = stack.peek();stack.pop();Integer left = stack.peek();int size = (i - left - 1) * heights[mid];maxSize = Math.max(size, maxSize);}stack.push(i);}}return maxSize;}
