【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;
    }
}
相关文章
|
3月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
5月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
264 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
3月前
|
算法 Java
50道java基础面试题
50道java基础面试题
|
5月前
|
缓存 Java 关系型数据库
Java 面试经验总结与最新 BAT 面试资料整理含核心考点的 Java 面试经验及最新 BAT 面试资料
本文汇总了Java面试经验与BAT等大厂常见面试考点,涵盖心态准备、简历优化、面试技巧及Java基础、多线程、JVM、数据库、框架等核心技术点,并附实际代码示例,助力高效备战Java面试。
204 0
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
316 4
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
2064 2

热门文章

最新文章