算法复习三【栈、队列】

7、栈

括号验证

思路:用栈去存储’(’ 、’{’ 、’[’,因为遇到的和栈出来的是会进行对应的,如果不对应或不存在则错误

public class StackUse{
	public boolean isValid(String s) {
		Stack<Character> stack=new Stack<Character>();
		for (char c : s.toCharArray()){
			if (c=='(' || c=='{' || c=='[') {
				stack.push(c); 
			}
			if (c==')') {
				if (stack.isEmpty() && stack.pop()!=')') {
					return false;
				}
			}
			if (c=='}') {
				if (stack.isEmpty() && stack.pop()!='}') {
					return false;
				}
			}
			if (c==']') {
				if (stack.isEmpty() && stack.pop()!=']') {
					return false;
				}
			}
		}
		return true;
    }
}
最小栈

思路:建立两个栈去实现,一个栈去对应当前栈的最小值,栈值取出一个,最小栈也取出,这样就可以保证最小栈的值是正确的,不会受变化的影响

public class MinStack{
	Stack<Integer> stack;
    Stack<Integer> minStack;
    public MinStack(){
        stack=new Stack<>();
		minStack=new Stack<>();
    }
    public void push(int value){
        if(minStack.isEmpty()){
            stack.push(value);
            minStack.push(value);
        }else{
            if(value>minStack.peek()){
            	minStack.push(minStack.peek());
            }else{
                minStack.push(value);
            }
            stack.push(value);
        }
    }
	public int pop(){
        if(!stack.isEmpty()){
            minStack.pop();
            return stack.pop();
        }
        return -1;
    }
    public int min(){
        if(!minStack.isEmpty()){
            return minStack.peek();
        }
        return -1;
    }
}
最大面积

思路:就是大于栈内的数,可以放入,因为可以和前面的叠一起增加x长度

而小于的就得出来,因为已经形成不了矩形,只能取出算可得的矩形面积结果

/**java
每次从栈中 pop 出一个数的时候,就找到了往左数比它小的第一个数(当前栈顶)和往右数比它小的第一个数(即将入栈的数),
从而可以计算出这两个数中间的部分宽度 * 被pop出的数,就是以这个被pop出来的数为最低的那个直方向两边展开的最大矩阵面积。
因为要计算两个数中间的宽度,因此放在 stack 里的是每个数的下标
*/
public class LargestArea {
	public int largestRectangleArea(int[] height) {
		if (height == null || height.length == 0) {
			return 0;
		}

		Stack<Integer> stack = new Stack<Integer>();
		int max = 0;
		for (int i = 0; i < height.length; i++) {
			int current =height[i];
			while (!stack.isEmpty() && current <= height[stack.peek()]) {
				int h = height[stack.pop()];
				int w = stack.isEmpty() ? i : i - stack.peek() - 1;
				max = Math.max(max, h * w);
			}
			stack.push(i);
		}
		return max;
	}
}

8、队列

两个栈实现队列:

思路:用两个栈,每一次存,都先存到第一个栈,需要拿的时候,在从第一个拿出来存到第二个,这样就顺序可以反过来了

等取完第二个,再继续将第一个栈倒过去。

public class MyQueue{
    //两个栈
	Stack<Integer> stack1;
	Stack<Integer> stack2;
	public MyQueue(){
		stack1=new Stack<Integer>();
		stack2=new Stack<Integer>();
	}
	//推的时候都推到第一个
	public void push(int element){
		this.stack1.push(element);
	}
    //拿的时候
	public int pop(){
		if (stack1.isEmpty() && stack2.isEmpty()) {
			return -1;
		}
        //如果第二个空的,就把第一个栈拿出来存进来
		if (stack2.isEmpty()) {
			while(!stack1.isEmpty()){
				stack2.push(stack1.pop());
			}
			return stack2.pop();
		}
		return stack2.pop();
	}
	public int peek(){
		if (stack1.isEmpty() && stack2.isEmpty()) {
			return -1;
		}
        //如果第二个空的,就把第一个栈拿出来存进来
		if (stack2.isEmpty()) {
			while(!stack1.isEmpty()){
				stack2.push(stack1.pop());
			}
			return stack2.peek();
		}
		return  stack2.peek();
	}
}
两个队列实现栈:

思路:存储的时候,先把第一个放第一队列,第二个放第二队列,然后第一队列的再加过来,接着第三个放第一队列一次进行调换。

public class MyStack {
    //两个队列
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    public MyStack(){
        queue1=new ArrayDeque<>();
        queue2=new ArrayDeque<>();
    }
    //取第二队列
    public int pop(){
        if(queue2.isEmpty()){
            return -1;
        }
       return queue2.poll();
    }
    //取第二队列的
    public int peek(){
        return queue2.peek();
    }
    
    public void push(int a){
        //把数放入第一队列
        queue1.add(a);
        //然后第二队列的加进来,就可以变成后进先出
        while (!queue2.isEmpty()){
            queue1.add(queue2.peek());
            queue2.remove();
        }
        //再第一队列的结果放回第二队列
        Queue<Integer> queue=queue2;
        queue2=queue1;
        queue1=queue;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值