算法总结之“堆栈队列”:6道必备题,搞定BAT(含解析+源代码)

本文介绍了数据结构中的栈和队列的基本概念,提供了Java实现栈和队列的代码示例,并展示了如何使用两个栈实现队列以及用队列实现栈。此外,还讨论了包含最小值功能的栈以及判断栈的压入、弹出序列的正确性的算法问题。这些内容对于理解和运用数据结构有重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

01 基础概念

:后进先出(LIFO)

队列:先进先出(FIFO)

02 栈的 java 实现

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import java.util.Arrays;

public class Stack {
    private int size = 0;  //栈顶位置
    private int[] array;

    public Stack(){
        this(10);
    }
    public Stack(int init) {   
        if(init <= 0){
            init = 10;
        }
        array = new int[init];
    }

    /**
     * 入栈操作
     * @param item 入栈的元素
     */
    public void push(int item){
        if(size == array.length){
            array = Arrays.copyOf(array, size*2);   //扩容操作
        }
        array[size++] = item;
    }

    /**
     * 获取栈顶元素,但栈顶元素不出栈
     * @return 栈顶元素
     */
    public int peek(){
        if(size == 0){  //空栈
            throw new IndexOutOfBoundsException("栈是空的");
        }
        return array[size-1];
    }

    /**
     * 出栈,同时获取栈顶元素
     * @return
     */
    public int pop(){
        int item = peek();  //获取栈顶元素
        size--;  //直接使元素个数减1,不用清除元素,下次入栈会覆盖旧元素的值
        return item;
    }

    /**
     * 判断栈是否已满
     * @return
     */
    public boolean isFull(){
        return size == array.length;
    }

    /**
     * 判断栈是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    public int getSize(){
        return size;
    }    
}</pre>

03 队列的 java 实现

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class ArrayQueue {
    private final Object[] queue;  //声明一个数组
    private int head;
    private int tail;

    /**
     * 初始化队列
     * @param capacity 队列长度
     */
    public ArrayQueue(int capacity){
        this.queue = new Object[capacity];
    }

    /**
     * 入队
     * @param o 入队元素
     * @return 入队成功与否
     */
    public boolean put(Object o){
        if(head == (tail+1)%queue.length){
            //说明队满
            return false;
        }
        queue[tail] = o;
        tail = (tail+1)%queue.length;  //tail标记后移一位
        return true;
    }

    /**
     * 返回队首元素,但不出队
     * @return
     */
    public Object peak() {
        if(head==tail){
            //队空
            return null;
        }
        return queue[head];        
    }

    /**
     * 出队
     * @return 出队元素
     */
    public Object pull(){
        if(head==tail){
            return null;
        }
        Object item = queue[head];
        queue[head] = null;
        return item;
    }

    /**
     * 判断是否为空
     * @return
     */
    public boolean isEmpty(){
        return head == tail;
    }

    /**
     * 判断是否为满
     * @return
     */
    public boolean isFull(){
        return head == (tail+1)%queue.length;
    }

    /**
     * 获取队列中的元素个数
     * @return
     */
    public int getsize(){
        if(tail>=head){
            return tail-head;
        }else{
            return (tail+queue.length)-head;
        }
    }    
}</pre>

04 用两个栈实现队列

剑指offer:用两个栈实现队列 LeetCode:Implement Queue using Stacks

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class MyQueue {
    Stack<Integer> input = new Stack<Integer>();
    Stack<Integer> output = new Stack<Integer>();
    /** Push element x to the back of queue. */
    public void push(int x) {
        input.push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        peek();
        return output.pop();
    }
    /** Get the front element. */
    public int peek() {
        if(output.isEmpty()){
            while(!input.isEmpty())
                output.push(input.pop());
        }
        return output.peek();
    }
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return input.isEmpty() && output.isEmpty();
    }
}</pre>

05 用队列实现栈

LeetCode:Implement Stack using Queues

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class MyStack {

    Queue<Integer> q1 = new LinkedList<Integer>();
    Queue<Integer> q2 = new LinkedList<Integer>();

    /** Push element x onto stack. */
    public void push(int x) {
        if(q1.isEmpty()){
            q1.add(x);
            for(int i = 0; i < q2.size(); i++){
                q1.add(q2.poll());
            }
        }else{
            q2.add(x);
            for(int i = 0; i < q1.size(); i++){
                q2.add(q1.poll());
            }
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return q1.isEmpty() ? q2.poll() : q1.poll();
    }

    /** Get the top element. */
    public int top() {
        return q1.isEmpty() ? q2.peek() : q1.peek();
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return q1.isEmpty() && q2.isEmpty();
    }
}</pre>

06 包含min函数的栈

剑指offer:包含min函数的栈 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class MinStack {
    Stack<Integer> stack = new Stack<Integer>();
    Stack<Integer> temp = new Stack<Integer>();

    public void push(int x) {
        stack.push(x);
        if(temp.isEmpty() || temp.peek() >= x)
            temp.push(x);
    }

    public void pop() {
        int x = stack.pop();
        int min = temp.peek();
        if(x == min)
            temp.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return temp.peek();
    }
}</pre>

07 栈的压入、弹出序列

剑指offer:栈的压入、弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public boolean IsPopOrder(int [] pushA, int [] popA) {
        if(pushA.length != popA.length || 
               pushA.length == 0 ||
               popA.length == 0)
            return false;
        Stack<Integer> stack = new Stack<>();
        int index = 0;
        for(int i = 0; i < pushA.length; i++){
            stack.push(pushA[i]);
            while(!stack.empty() && stack.peek() == popA[index]){
                stack.pop();
                index++;
            }
        }
        return stack.empty();
    }
}</pre>

08 总结

面试时问到算法,好多小伙伴都闻风丧胆,跪在此处(很可惜~)。光有这6道堆栈与队列的算法题是远远不够的,因此,再给各位小伙伴免费分享一个《算法刷题大全》,可直接看文末

  • 第1章 编程技巧
  • 第2章 线性表

  • 第3章 字符串
  • 第4章 栈和队列
  • 第5章 树

  • 第6章 排序
  • 第7章 查找
  • 第8章 暴力枚举法
  • 第9章 广度优先搜索
  • 第10章 深度优先搜索

  • 第11章 分治法
  • 第12章 贪心法
  • 第13章 动态规划
  • 第14章 图
  • 第15章 细节实现题

这份算法刷题大全PDF文档总共就是这15章,需要可领

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值