4.栈
栈
先进后出,栈顶进出
1.基本操作
/**
* 数组模拟栈
*/
public class StackAarry {
private int maxSize;
private int[] stack;
private int top = -1;
//构造
public StackAarry(int maxSize) {
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
//栈满
public boolean isFull() {
return top == this.maxSize - 1;
}
//栈空
public boolean isEmpty() {
return top == -1;
}
//入栈
public void push(int value) {
if (isFull()) {
System.out.println("栈满");
return;
}
stack[++top] = value;
}
//出栈
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空");
}
return stack[top--];
}
//显示
public void list() {
if (isEmpty()) {
System.out.println("栈空");
return;
}
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d]=%d ", i, stack[i]);
}
}
}
2.应用
2.1 单调栈
2.1.1直方图中最大矩形的面积

/**
* 直方图中最大矩形的面积
* 栈内储存连续的升序值(此题储存的是数组序号,对应数组值递增)
* 每遇到断点,则依次出栈算面积,直至栈空或满足升序
*/
public class Solution {
/**
* @param height int整型一维数组
* @return int整型
*/
public int largestRectangleArea (int[] height) {
if(height.length < 1) return 0;
Stack<Integer> sta = new Stack<Integer>();
sta.push(-1);//标记栈空
int ans = 0;
for(int i = 0;i < height.length;i++){
//每遇到不单调的点,就进行一轮计算,直到栈空或单调
while(sta.peek() != -1 && height[i] < height[sta.peek()]{
int top = sta.pop();
ans = Math.max(ans, height[top] * (i - 1 - sta.peek()));
}
sta.push(i);
}
//此时栈仍未空,仍要进行一轮计算,直到栈空
while(sta.peek() != -1){
int top = sta.pop();
ans = Math.max(ans, height[top] * (height.length - 1 - sta.peek()));
}
return ans;
}
}
2.1.2收集雨水

/**
* 给出n个数字,表示一个高程图,高程图中每一条的宽度为1,请计算下雨之后这个地形可以存储多少水
* 例如给出[0,1,0,2,1,0,1,3,2,1,2,1],返回6.
*/
public class Solution {
public int trap (int[] A) {
if(A == null || A.length < 2) return 0;
Stack<Integer> st = new Stack<Integer>();
int sum = 0;
for(int i = 0;i < A.length;i++){
while(!st.empty() && A[i] > A[st.peek()]){
//每次计算的面积
int bottom = A[st.pop()];
int top = st.empty() ? 0 : Math.min(A[i],A[st.peek()]);
int leftpos = st.empty() ? -1 : st.peek();
//栈空时无有效面积
if(top > bottom) sum += (top - bottom) * (i - 1 - leftpos);
}
st.push(i);
}
return sum;
}
}
如果自己都不相信自己了,那该如何呢?

浙公网安备 33010602011771号