[算法总结] 6 道题搞定 BAT 面试——堆栈和队列
本文首发于我的个人博客:尾尾部落
0. 基础概念
栈:后进先出(LIFO)

队列:先进先出(FIFO)

1. 栈的 java 实现
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;
    }
}
2. 队列的 java 实现
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;
        }
    }
}
3. 用两个栈实现队列
剑指offer:用两个栈实现队列
LeetCode:Implement Queue using Stacks
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();
    }
}
4. 用队列实现栈
LeetCode:Implement Stack using Queues
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();
    }
}
5. 包含min函数的栈
剑指offer:包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
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();
    }
}
6. 栈的压入、弹出序列
剑指offer:栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
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();
    }
}
[算法总结] 6 道题搞定 BAT 面试——堆栈和队列的更多相关文章
- [算法总结] 13 道题搞定 BAT 面试——字符串
		1. KMP 算法 谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置.KMP 算法把字符匹配的时间复杂度缩小到 O(m+ ... 
- [算法总结] 20 道题搞定 BAT 面试——二叉树
		本文首发于我的个人博客:尾尾部落 0. 几个概念 完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边.想到点什么没?实际上 ... 
- 【搞定Jvm面试】 Java 内存区域揭秘附常见面试题解析
		本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ... 
- 【搞定Jvm面试】 JVM 垃圾回收揭秘附常见面试题解析
		JVM 垃圾回收 写在前面 本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好 ... 
- 搞定redis面试--Redis的过期策略?手写一个LRU?
		1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ... 
- 搞定PHP面试 - 变量知识点整理
		一.变量的定义 1. 变量的命名规则 变量名可以包含字母.数字.下划线,不能以数字开头. $Var_1 = 'foo'; // 合法 $var1 = 'foo'; // 合法 $_var1 = 'fo ... 
- 【搞定Jvm面试】 JDK监控和故障处理工具揭秘
		本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ... 
- 【Javascript】搞定JS面试——跨域问题
		什么是跨域? 为什么不能跨域? 跨域的解决方案都有哪些(解决方法/适用场景/get还是post)? 一.什么是跨域? 只要协议.域名.端口有任何一个不同,就是跨域. ... 
- 30秒搞定String面试
		Java 语言中,无论新菜鸟,还是老司机,真正了解String内存的很少.关于String 的试题,花样很多.== 在什么情况下是true,什么情况是false.我总结出如下3点让你彻底结束对Stri ... 
随机推荐
- 再谈全局网HBase八大应用场景
			摘要: HBase可以说是一个数据库,也可以说是一个存储.拥有双重属性的HBase天生就具备广阔的应用场景.在2.0中,引入了OffHeap降低了延迟,可以满足在线的需求.引入MOB,可以存储10M左 ... 
- [ML学习笔记] XGBoost算法
			[ML学习笔记] XGBoost算法 回归树 决策树可用于分类和回归,分类的结果是离散值(类别),回归的结果是连续值(数值),但本质都是特征(feature)到结果/标签(label)之间的映射. 这 ... 
- codeforces 671D Roads in Yusland & hdu 5293 Tree chain problem
			dp dp优化 dfs序 线段树 算是一个套路.可以处理在树上取链的问题. 
- HTML DOM item() 方法
			一直不知道javascript还有类似jQ里面eq()的函数,原来原生javascript的item()有类似功能: 由于是原生javascript,先补习下children和childNodes的区 ... 
- HTML5API之获取地理位置详解
			在使用地理位置API之前先来了解一下什么是经度和纬度以及地理位置获取的原理 首先经度指的是南北极的连接线,纬度指的是东西的连接线 地理位置的获取原理是通过IP地址(基于ISP记录,能够知道这个IP地址 ... 
- Postman-断言和Runner
			断言(部分) // 推荐用全等 ===,确保类型和值都一致 tests['Status code is 200'] = responseCode.code === 200; //判断响应结果是否是20 ... 
- velocity模板实战
			场景:json配置报文转换遇到的问题:1.json报文转换成map,多节点如何处理?数组如何处理? 2.velocity模板处理数组 3.应用之间rabbitmq通讯map反序列化,数组报错?知识点: ... 
- JAVA框架  Spring 依赖注入
			一:介绍 情景:我们在给程序分层的时候:web层.业务层.持久层,各个层之间会有依赖.比如说:业务层和持久层,业务层的代码在调用持久层的时候,传统方式:new 持久层类. 进而进行调用,这种方式会导致 ... 
- 关于YARN Node Labels的一点理解
			最近在做实验,实验需要进行分区域计算,网上查了资料后发现Yarn Node Labels + Capacity-Scheduler可以实现我的需求 但是当任务提交到capacity-scheduler ... 
- Controller中添加一个异步的Action
			给一段示例代码: public Task<ActionResult> TbReport(string code) { return Task.Factory.StartNew(() =&g ... 
