【Java数据结构】栈与队列 经典面试题——刷题笔记(下)

简介: 笔记

4. 用栈实现队列


题目:

35.png


思路:

队列是先进先出,需要用到两个栈才能实现队列

指定S1为输入栈,S2为输出栈

入队时,直接将元素压入S1栈即可

出队时,要将输入栈S1中的元素依次出栈,并压入输出栈S2中,然后将S2栈顶元素出栈,这样就能实现先入队的元素先出队,有一点要注意,只有S2为空的时候,才能将输入栈S1中的元素移到S2中,不然会打乱队列顺序!

36.gif


实现代码:

class MyQueue {
    //创建两个栈
    Stack<Integer> s1;//输入栈
    Stack<Integer> s2;//输出栈
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    public void push(int x) {
        s1.push(x);//入队直接将元素压入S1即可
    }
    public int pop() {
        int size = s1.size();//出队时,将s1中所以元素移至s2中
        if(!s2.isEmpty()){
            return s2.pop();//s2不为空,则直接弹出栈顶元素即可
        }else{
          for(int i=0; i<size; i++){//否则要将s1中元素转移到s2中再弹出s2栈顶元素
              int tmp = s1.pop();
              s2.push(tmp);
            }
        return s2.pop();
        }
    }
    public int peek() {//和出队方法一样,只不过由删除变成查看,只看不删
        int size = s1.size();
        if(!s2.isEmpty()){
            return s2.peek();
        }else{
          for(int i=0; i<size; i++){
              int tmp = s1.pop();
              s2.push(tmp);
            }
        return s2.peek();
        }
    }
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }
}


5. 设计循环队列


题目:

37.png


思路:


要设计一个循环队列,用到的是一个数组,需要设置一个front下标表示队列首元素,rear下标,表示尾元素后一个可用位置的下标

有三个关键问题要解决:

①front和rear相遇之后,队列到底是空了还是满了?

答:每次再放元素的时候,都去判断rear位置的下一个位置是不是front,如果是,就满了,所以要预留一个空间,不放元素

②rear每次存放完成之后,能不能进行rear=rear+1

③front每次出队之后,能不能进行front=front+1

答:rear和front都不能直接+1,因为假设7个元素的循环队列,下标走到6了,6+1=7 数组此时能访问7下标嘛?不能,所以研究处一个公式rear/front = (rear/front+1)%len就能表示下一个位置了

38.gif



实现代码:


class MyCircularQueue {
    private int[] elem; //数组
    private int front;// 头
    private int rear;//尾巴下标   当前可以存放元素的下标
    public MyCircularQueue(int k) {
        //这里为什么是k+1: 题的描述指定要放k个,因为用我的方法实现的时候就是多一个空间出来的
        this.elem = new int[k+1];
        this.rear = 0;
        this.front = 0;
    }
    //入队
    public boolean enQueue(int value) {
        if(isFull()) //判断循环队列满了没有
        return false;//满了就返回false
        this.elem[this.rear] = value;//没满就给rear位置插入元素
        this.rear = (this.rear+1)%this.elem.length;//然后rear下标往后走一步
        //this.rear = this.rear+1;
        return true;
    }
    //删除  出队
    public boolean deQueue() {
         if(isEmpty()) {//先判断循环队列是否空
            return false;//空的就返回false
        }
        //循环队列不为空,就将首元素位置,front往后走一步
        //原来的元素会被以后加入的覆盖掉,或者不再能被访问到
        this.front = (this.front+1)%this.elem.length;
        return true;
    }
    //得到队头元素
    public int Front() {
         if(isEmpty()) {//依旧先判断是否为空
            return -1;
        }
        return this.elem[this.front];
    }
    //得到队尾元素  注意:当rear == 0下标的时候
    public int Rear() {
         if(isEmpty()) {//依旧先判断是否为空
            return -1;
        }
        //这里注意一个问题,我们已经知道rear-1位置就是队尾元素,可是当rear=0的时候,0-1=-1,这样不就出错了?所以遇到这种情况的时候用 循环队列的长度-1 就是0下标的上一个位置了
        int index = (this.rear == 0) ? this.elem.length-1 : this.rear-1;
        return this.elem[index];
    }
    public boolean isEmpty() {
        //只要他两相遇了 那么就是空的队列
        if(this.front == this.rear) {
            return true;
        }
        return false;
    }
    public boolean isFull() {
        //判断rear位置的下一个位置是不是front,如果是,就满了
        if((this.rear+1) % this.elem.length == this.front) {
            return true;
        }
        return false;
    }
}
相关文章
|
5天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
18 2
|
10天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
16天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
12天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
37 4
|
13天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
53 4
|
SQL 缓存 安全
Java高频面试题目
面试时面试官最常问的问题总结归纳!
143 0
JAVA高频面试题目集锦(6)
JAVA高频面试题目集锦(6)
141 0
JAVA高频面试题目集锦(6)
|
存储 安全 Java
JAVA高频面试题目集锦(5)
JAVA高频面试题目集锦(5)
185 0
JAVA高频面试题目集锦(5)
|
算法 安全 Java
JAVA高频面试题目集锦(4)
JAVA高频面试题目集锦(4)
106 0
JAVA高频面试题目集锦(4)
|
存储 Java 对象存储
JAVA高频面试题目集锦(3)
JAVA高频面试题目集锦(3)
119 0
JAVA高频面试题目集锦(3)