一. 单调栈介绍
是一种 栈, 对于出栈顺序递增叫单调递增栈,递减叫单调递减栈。
二. 相关例题
2.1 最大矩形
leetcode 85. 最大矩形
https://leetcode-cn.com/problems/maximal-rectangle
class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int maxArea = 0;
int[] res = new int[matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
res[j] = matrix[i][j] == '0' ? 0 : res[j] + 1;
}
maxArea = Math.max(getMaxArea(res), maxArea);
}
return maxArea;
}
public int getMaxArea(int[] height){
if (height == null || height.length == 0){
return 0;
}
int res = 0;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]){
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int tem = (i - k - 1) * height[j];
res = Math.max(res, tem);
}
stack.push(i);
}
while (!stack.isEmpty()) {
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int tem = (height.length - k - 1) * height[j];
res = Math.max(res, tem);
}
return res;
}
}
2.2 柱状图中最大的矩形
leetcode 84. 柱状图中最大的矩形
https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
class Solution {
public int largestRectangleArea(int[] heights) {
if(heights == null || heights.length == 0){
return 0;
}
Stack<Integer> stack = new Stack();
int res = 0;
for(int i = 0; i < heights.length; i++){
while(!stack.isEmpty() && heights[i] <= heights[stack.peek()]){
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int tem = (i - k - 1)*heights[j];
res = Math.max(res, tem);
}
stack.push(i);
}
while(!stack.isEmpty()){
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int tem = (heights.length - k - 1)*heights[j];
res = Math.max(res, tem);
}
return res;
}
}
2.3 保卫方案
京东2017年笔试原题
https://www.nowcoder.com/questionTerminal/e1967ae812ea42e7a3ce57ee1f83b686
import java.util.Stack;
public class 保卫方案 {
public static class Pair{
public int value;
public int times;
public Pair(int value){
this.value = value;
this.times = 1;
}
}
public static long communications(int[] arr){
if (arr == null || arr.length == 0){
return 0;
}
int size = arr.length;
int maxIndex = 0;
for (int i = 0; i < size; i++) {
maxIndex = arr[maxIndex] < arr[i] ? i : maxIndex;
}
int value = arr[maxIndex];
int index = nextIndex(size, maxIndex);
long res = 0L;
Stack<Pair> stack = new Stack<>();
stack.push(new Pair(value));
while (index != maxIndex){
value = arr[index];
while(!stack.isEmpty() && stack.peek().value < value){
int times = stack.pop().times;
res += getInternalSum(times) + 2 * times;
}
if (!stack.isEmpty() && stack.peek().value == value){
stack.peek().times++;
}else{
stack.push(new Pair(value));
}
index = nextIndex(size, index);
}
while (!stack.isEmpty()){
int times = stack.pop().times;
res += getInternalSum(times);
if (!stack.isEmpty()){
res += times;
if (stack.size() > 1){
res += times;
}else{
res += stack.peek().times > 1 ? times : 0;
}
}
}
return res;
}
public static int nextIndex(int size, int i){
return i < (size - 1) ? i + 1 : 0;
}
public static long getInternalSum(int n){
return n == 1L ? 0L : (long)n * (long)(n - 1) / 2L;
}
public static void main(String[] args) {
int[] a = new int[]{1, 2, 4, 5, 3};
System.out.println(communications(a));
}
}