刷题(四)--栈和队列

判断出栈序列

题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

示例1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

思路如下:
我们可以借助一个辅助栈stack,模拟压入和弹出的操作。并且我们可以根据是否模拟成功得到结果。入栈的时候,按照压栈序列执行,在每次出栈的时候判断栈顶元素和弹出序列当前元素是否相等,如果都符合会在结束时栈空,否则为不符合。
代码:

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
    Stack<Integer> stcack = new Stack<>();
    int i = 0;
    for(int num:pushed){
        stcack.push(num);
        while(!stcack.isEmpty()&&stcack.peek()==popped[i]){
            stcack.pop();
            i++;
        }
    }
    return stcack.isEmpty();
    }
}

复杂度:
时间复杂度 O(N) : 其中 N 为列表 pushedpushed 的长度;每个元素最多入栈与出栈一次,即最多共 2N 次出入栈操作。
空间复杂度 O(N) : 辅助栈 stack 最多同时存储 N 个元素。

两个队列模拟一个栈

使用两个队列模拟栈的出入操作,入栈时把数据直接加进一个队列,出栈时,先判断是否队列为空,如果一个不为空,那么这个队列的末尾元素即为要出战的元素。

class MyStack<T>{
     private Queue queue01=new LinkedList();//用于入栈
     private Queue queue02=new LinkedList();//用于出栈
 
    /**
     * 实现出栈操作:出栈操作比进栈操作麻烦点
     * @return
     */
     public T pop(){
         //如果queue01和queue02都为空,则模拟栈中为空
         if(queue01.isEmpty() && queue02.isEmpty()){
             return null;
         }
         //如果queue01不为空,且size>1 先出队列,剩最后一个元素为要出栈的元素
         while(!queue01.isEmpty()){
             if(queue01.size()<=1){
                 return (T)queue01.poll();
             }else{
                 queue02.offer(queue01.poll());
             }
         }
         //如果queue01为空queue02不为空 则将queue2的元素出队列,进到queue01 剩最后一个元素为需要出栈的元素
         if(queue01.isEmpty() && !queue02.isEmpty()){
             while(!queue02.isEmpty()){
                 if(queue02.size()<=1){
                     return (T)queue02.poll();
                 }else{
                     queue01.offer(queue02.poll());
                 }
             }
         }
         return null;
     }
 
    /**
     * 实现入栈操作
     *
     * @param node
     */
     public void push(T node){
         queue01.offer(node);
     }
 
    /**
     * 模拟栈的大小
     * @return
     */
     public int size(){
         return queue01.size()+queue02.size();
     }
}

两个栈模拟一个队列

题目描述:用两个栈实现队列,支持队列的基本操作。

输入描述:
第一行输入一个整数N,表示对队列进行的操作总数。
下面N行每行输入一个字符串S,表示操作的种类。
如果S为"add",则后面还有一个整数X表示向队列尾部加入整数X。
如果S为"poll",则表示弹出队列头部操作。
如果S为"peek",则表示询问当前队列中头部元素是多少。

输出描述:
对于每一个为"peek"的操作,输出一行表示当前队列中头部元素是多少。

示例1:

输入:
6
add 1
add 2
add 3
peek
poll
peek

输出:
1
2

代码:

import java.util.Scanner;
import java.util.Stack;

public class Main {
    private static Stack<Integer> stackPush;
    private static Stack<Integer> stackPop;

    public static void main(String[] args) {
        stackPush = new Stack<>();
        stackPop = new Stack<>();
        Scanner scanner = new Scanner(System.in);
        int n = Integer.valueOf(scanner.nextLine());
        String string;
        for (int i = 0; i < n; i++) {
            string = scanner.nextLine();
            if (string.equals("poll")) {
                poll();
            } else if (string.equals("peek")) {
                System.out.println(peek());
            } else {
                add(Integer.valueOf(string.split(" ")[1]));
            }
        }
    }

    public static void add(int number) {
        stackPush.push(number);
    }

    public static int poll() {
        if (stackPush.empty() && stackPop.empty()) {
            throw new RuntimeException("Your queue is empty!");
        }
        pushToPop();
        return stackPop.pop();
    }

    public static int peek() {
        if (stackPush.empty() && stackPop.empty()) {
            throw new RuntimeException("Your queue is empty!");
        }
        pushToPop();
        return stackPop.peek();
    }

    private static void pushToPop() {
        if (stackPop.empty()) {
            while (!stackPush.empty()) {
                stackPop.push(stackPush.pop());
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

降温vae+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值