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直方图中最大矩形的面积

image

/**
* 直方图中最大矩形的面积
* 栈内储存连续的升序值(此题储存的是数组序号,对应数组值递增)
* 每遇到断点,则依次出栈算面积,直至栈空或满足升序
*/
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收集雨水

image

/**
* 给出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;        
    }
}
posted @ 2021-04-06 09:48  FremontUltimate  阅读(68)  评论(0)    收藏  举报