棧(Stack)與隊列(Queue)

定義

棧:後進先出(LIFO-last in first out):最後插入的元素最先出來。
隊列:先進先出(FIFO-first in first out):最先插入的元素最先出來。

圖示

在這裏插入圖片描述

本文通過一些簡單的算法題來帶你們更好的理解棧(Stack)和隊列(Queue)。

第一題

題目:獲取一個棧的min

定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。

import java.util.Stack;

/**
 * @author god-jiang
 * @date 2020/1/6
 */
public class GetMinStack {
    //正常stack
    Stack<Integer> stack = new Stack<>();
    //存放min的stack
    Stack<Integer> help = new Stack<>();

    public void push(int node) {
        stack.push(node);
        if (help.isEmpty()) {
            help.push(node);
        } else {
            //help裏面存放的都是最小值,也就是pop之後裏面是當前的最小值
            int res = help.peek() > node ? node : help.peek();
            help.push(res);
        }
    }

    public void pop() {
        stack.pop();
        help.pop();
    }

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

    public int min() {
        return help.peek();
    }
}

第二題

題目:用棧實現隊列

思路:構建兩個棧(Push棧和Pop棧);將Push棧中的數據導入Pop棧中然後返回給用戶,就實現了隊列。需要注意兩個條件:①Pop棧爲空時才能往裏面倒數據。②向Pop棧倒數據必須全部倒完。

import java.util.Stack;

/**
 * @author god-jiang
 * @date 2020/1/6
 */
public class StackToQueue {
    //用s1、s2避免代碼看起來混亂,因爲都是push和pop操作
    private Stack<Integer> s1;
    private Stack<Integer> s2;

    public StackToQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    public void add(int obj) {
        s1.push(obj);
    }

    public Integer poll() {
        if (s1.isEmpty() && s2.isEmpty()) {
            throw new RuntimeException("empty");
        }
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.pop();
    }

    public Integer peek() {
        if (s1.isEmpty() && s2.isEmpty()) {
            throw new RuntimeException("empty");
        }
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }
}

第三題

題目:用隊列實現棧

思路:構建兩個隊列:queue隊列和help隊列;壓入數據時數據都進queue隊列,假設隊列中進入了1、2、3、4、5,返回數據時,把1、2、3、4放入help隊列,然後拿出queue的5返回。接着把queue隊列和help隊列的引用交換。即下次返回數據還是從queue隊列拿1、2、3、放入help隊列,然後queue拿出4返回,再交換各自的引用,一直重複。

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author god-jiang
 * @date 2020/1/6
 */
public class QueueToStack {
    private Queue<Integer> queue;
    private Queue<Integer> help;

    public QueueToStack() {
        queue = new LinkedList<>();
        help = new LinkedList<>();
    }

    public void push(Integer e) {
        queue.add(e);
    }

    public int pop() {
        if (queue.isEmpty()) {
            throw new RuntimeException("empty");
        }
        while (queue.size() != 1) {
            help.add(queue.poll());
        }
        int res = queue.poll();
        swap();
        return res;
    }

    public int peek() {
        if (queue.isEmpty()) {
            throw new RuntimeException("empty");
        }
        while (queue.size() != 1) {
            help.add(queue.poll());
        }
        int res = queue.poll();
        help.add(res);
        swap();
        return res;
    }

    public void swap() {
        Queue<Integer> tmp = queue;
        queue = help;
        help = tmp;
    }
}

總結

就是把棧跟隊列的特點介紹了一下,然後用三道經典的題目來加深對棧和隊列的理解,然後附上我自己寫的代碼,都是經過測試後才附上的。有什麼問題,歡迎與我交流和討論,我的目的就是大家一起學習一起進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章