左神算法整理笔记06

利用数组实现栈和队列

用数组实现栈

public class ArrayStack {

    private Integer[] arr;
    private Integer size;
	
	// 初始化
    public ArrayStack(int initSize) {
        if (initSize < 0) {
            throw new IllegalArgumentException("the init size is less than 0");
        }
        arr = new Integer[initSize];
        size = 0;
    }
	// 顶
    public Integer peek() {
        if (size == 0) {
            return null;
        }
        return arr[size-1];
    }
	// 添加元素
    public void push(int obj) {
        if (size == arr.length) {
            throw new ArrayIndexOutOfBoundsException("the queue is full");
        }
        arr[size++] = obj;
    }
	// 弹出元素
    public Integer pop() {
        if (size == 0) {
            throw new ArrayIndexOutOfBoundsException("the queue is empty");
        }
        return arr[--size];
    }
}

用数组实现队列

  • start和end的策略:只要到底了,就会跳到开头
public class ArrayQueue {

    private Integer[] arr;
    // 用三个变量就能很快写出来,而不需要扣细节
    // start变量表示如果弹出一个元素,应该是哪一个位置上的
    private Integer start;
    // end变量表示如果添加一个元素,应该放在哪一个位置上
    private Integer end;
    // 利用size来约束start和end, start和end之间是解耦的
    private Integer size;

    public ArrayQueue(Integer initSize) {
        if (initSize < 0) {
            throw new IllegalArgumentException("the init size is less than 0");
        }
        arr = new Integer[initSize];
        start = 0;
        end = 0;
        size = 0;
    }

    public Integer peek() {
        if (size == 0) {
            return null;
        }
        return arr[start];
    }

    public void push (Integer obj) {
        if (size == arr.length) {
            throw new ArrayIndexOutOfBoundsException("the queue is full");
        }
        size++;
        arr[end] = obj;
        // end只要到底了,就会跳到开头,所以需要一个size来维护长度
        end = end == arr.length-1 ? 0 : end + 1;
    }

    public Integer poll() {
        if (size == 0) {
            throw new ArrayIndexOutOfBoundsException("the queue is empty");
        }
        size--;
        Integer tmp = start;
        // end只要到底了,就会跳到开头,所以需要一个size来维护长度 
        start = start == arr.length - 1 ? 0 : start + 1;
        return arr[tmp];
    }
}

实现特殊的栈

实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作
要求:

  1. pop、push、getMin操作的时间复杂度都是O(1)
  2. 设计的栈类型可以使用现成的栈结构
public class _30_包含min函数的栈 {
    /** initialize your data structure here. */
    // 两个栈:一个做数据栈,一个做最小栈
    // 用额外空间:多维护一个最小栈,来保存最小值在栈顶;最小堆结构也可以实现
    private Stack<Integer> dataStack;
    private Stack<Integer> minStack;
    public _30_包含min函数的栈() {
        minStack = new Stack<Integer>();
        dataStack = new Stack<Integer>();
    }
    public void push(int x) {
        dataStack.push(x);
        // 最小栈存数据,这里有等于号
        if(minStack.isEmpty() || minStack.peek() >= x){
            minStack.push(x);
        }
    }
    public void pop() {
        // 比较的是Integer,需要用equals
        // 如果pop正好是最小栈的最小值,应该pop出去,因为这个数据已不存在
        if(dataStack.pop().equals(minStack.peek())){
            minStack.pop();
        }

    }
    public int top() {
        return dataStack.peek();
    }
    public int min() {
        return minStack.peek();
    }
}

// 另外一种设计; push的时候如果大,则push栈peek的数,这样pop的时候就不需要判断
public void push(int x) {
    dataStack.push(x);
    // 最小栈存数据,这里有等于号
    if(minStack.isEmpty()){
        minStack.push(x);
    } else if (minStack.peek() >= x){
    	minStack.push(x);
    } else {
    	minStack.push(minStack.peek());
    }
}
public void pop() {
	dataStack.pop();
    minStack.pop();
}

仅用栈结构实现队列

public class _09_两个栈实现队列 {
	// 输入栈,输出栈
    private Stack<Integer> inStack;
    private Stack<Integer> outStack;

    public _09_两个栈实现队列() {
        inStack = new Stack<>();
        outStack = new Stack<>();
    }

    // 在队列尾部插入元素;
    public void appendTail(int value) {
        inStack.push(value);
    }

    // 在删除队列头部元素;
    public int deleteHead() {
    	// 当输出栈为空的时候,才能进行转换数据操作
        if(outStack.isEmpty()){
            while(!inStack.isEmpty()){
                outStack.push(inStack.pop());
            }
        }
        // 输出栈输出数据
        return outStack.isEmpty() ? -1 : (int)outStack.pop();
    }
}

仅用队列结构实现栈

public class TwoQueue {

    Queue<Integer> a = new LinkedList<Integer>();
    Queue<Integer> b = new LinkedList<Integer>();

    //a入栈
    public void push(int node) {
        a.offer(node);
        while(!b.isEmpty()){
            b.offer(a.poll());
        }
        Queue temp=a;
        a=b;
        b=a;
    }
    
    public int pop() {
         return b.poll();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值