题目连接
leetcode:leetcode.cn/problems/la…
稀土掘金:www.marscode.cn/practice/8e…
题目
解法一:动态规划
定义 dp[i][j] 表示从 i 到 j 的最小值, 即柱子的最小高度。
初始可知道:dp[i][i] = array[i]
dp的状态转移方程为:dp[i][j] = min(dp[i][j-1],dp[j][j]),且j > i;
位置i到j的面积为:area = dp[i][j] * (j-i + 1)
最后,双层for循环dp,取最大 maxArea 返回。
该解法时间复杂度为:O(n^2)
public class Main {
public static int min(int a, int b) {
if (a > b) {
return b;
}
return a;
}
public static int solution(int n, int[] array) {
int len = array.length;
int[][] dp = new int[len][len];
for (int i = 0; i < len; i++) {
dp[i][i] = array[i];
for (int j = i + 1; j < len; j++) {
dp[i][j] = min(dp[i][j - 1], array[j]);
}
}
int res = 0;
for (int i = 0; i < len; i++) {
for (int j = i; j < len; j++) {
int s = (j - i + 1) * dp[i][j];
if (res < s) {
res = s;
}
}
}
return res;
}
public static void main(String[] args) {
System.out.println(solution(5, new int[] { 1, 2, 3, 4, 5 }) == 9);
}
}
解法二:单调栈
初始将第一个数据压入栈内,遍历后面的数据,
遍历每一个数据,和栈顶元素进行对比:
- 如果大于等于栈顶元素,将遍历的当前数据押入栈内。
- 如果小于栈顶元素,弹出栈顶元素作为矩形的高度。计算面积。
时间复杂度:O(n)
public int largestRectangleArea(int[] heights) {
List<Integer> hs = new ArrayList<>();
for (int i = 0; i < heights.length; i++) {
hs.add(heights[i]);
}
hs.add(0); // 添加0用于处理边界问题。
Stack<Integer> stack = new Stack<>();
stack.add(-1); // 添加-1用于处理边界问题,防止出现越界情况
stack.add(0);
int maxArea = 0;
for (int i = 1; i < hs.size(); i++) {
int cur = hs.get(i);
while (true) {
int stackTopNumIndex = stack.get(stack.size() - 1);
if (stackTopNumIndex == -1 || hs.get(stackTopNumIndex) <= cur) {
stack.add(i);
break;
} else {
stack.pop();
int stackTopNumIndex_2 = stack.get(stack.size() - 1);
int weight = (i - stackTopNumIndex) + (stackTopNumIndex - stackTopNumIndex_2) - 1;
int area = weight * hs.get(stackTopNumIndex);
if (maxArea < area) {
maxArea = area;
}
}
}
}
return maxArea;
}