Algorithms - Array | Stack | queue

An array of stacks and queues using analog

Analog using an array stack, comprising a stack push, pop, and peek operation.

public class ArrayStack {
    private Integer[] arr;
    private Integer size;

    public ArrayStack(int initSize) {
        if (initSize < 0) {
            throw new IllegalArgumentException("栈的大小不能小于 0");
        }
        arr = new Integer[initSize];
        size = 0;
    }

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

    public void push(Integer number) {
        if (size == arr.length) {
            throw new ArrayIndexOutOfBoundsException("栈已满!");
        }
        arr[size++] = number;
    }

    public Integer pop() {
        if (size == 0) {
            throw new ArrayIndexOutOfBoundsException("栈已空!");
        }
        return arr[--size];
    }
}

Analog queue using an array, comprising offer queue, poll and peek operation.

public class ArrayQueue {
    private Integer[] arr;
    private Integer size;
    private Integer first;
    private Integer last;

    public ArrayQueue(int initSize) {
        if (initSize < 0) {
            throw new IllegalArgumentException("队列长度不能小于 0!");
        }
        arr = new Integer[initSize];
        size = 0;
        //first 指向队首的位置
        first = 0;
        //last 指向队尾后空的位置
        last = 0;
    }

    public void offer(int number) {
        if (size == arr.length) {
            throw new ArrayIndexOutOfBoundsException("队列已满!");
        }
        arr[last++] = number;
        last = last < arr.length ? last : 0;
        size++;
    }

    public Integer poll() {
        if (size == 0) {
            throw new ArrayIndexOutOfBoundsException("队列已空!");
        }
        int res =  arr[first++];
        first = first < arr.length ? first : 0;
        size--;
        return res;
    }

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

() Operation time of design complexity getMin O (1) of the stack

Design of a stack, the stack operation of obtaining a minimum value of O (1), both the stack push, pop function.

public class MyStack {
    private Stack<Integer> stackData;
    private Stack<Integer> stackMin;

    public MyStack() {
        this.stackData = new Stack<>();
        this.stackMin = new Stack<>();
    }

    public void push(int number) {
        if (this.stackMin.isEmpty()) {
            this.stackMin.push(number);
        } else {
            int temp = this.stackMin.peek();
            if (temp < number) {
                this.stackMin.push(temp);
            } else {
                this.stackMin.push(number);
            }
        }
        this.stackData.push(number);
    }

    public Integer pop() {
        if (this.stackData.isEmpty()) {
            throw new RuntimeException("栈已空!");
        }
        this.stackMin.pop();
        return this.stackData.pop();
    }

    public Integer getMin() {
        if (this.stackData.isEmpty()) {
            throw new RuntimeException("栈已空!");
        }
        return this.stackMin.peek();
    }
}

Use the stack queue

stack1 designed to add data offer (), stack2 designed to view and pop-up data peek () poll ().

addStack2 () has two premises:

  • stack1 non-empty
  • stack1 need to transfer all the data to stack2
public class StackToQueue {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    public StackToQueue() {
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }

    public void offer(int number) {
        this.stack1.push(number);
        addStack2();
    }

    public Integer peek() {
        if (this.stack2.isEmpty()) {
            return null;
        }
        return this.stack2.peek();
    }

    private void addStack2() {
        while (!this.stack1.isEmpty()) {
            this.stack2.push(this.stack1.pop());
        }
    }

    public Integer poll() {
        if (this.stack2.isEmpty()) {
            throw new RuntimeException("队列已空!");
        }
        return this.stack2.pop();
    }
}

Use queue implementation Stack

Two queues is a store queue, a queue is help.

helper()

  • Transferring data queue to queue the queue help, leaving only one element of the queue tail of the queue as a return value

swap()

  • The reference queue queue queue and help swap
public class QueueToStack {
    private Queue<Integer> queue;
    private Queue<Integer> help;

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

    public void push(int number) {
        queue.offer(number);
    }

    public Integer peek() {
        if (queue.isEmpty()) {
            return null;
        }
        int res = helper();
        help.offer(res);
        swap();
        return res;
    }

    //将数据从 queue 转移到 help 中,留下一个数
    private Integer helper() {
        while (queue.size() > 1) {
            help.offer(queue.poll());
        }
        return queue.poll();
    }

    private void swap() {
        Queue<Integer> temp = queue;
        queue = help;
        help = temp;
    }

    public Integer pop() {
        if (queue.isEmpty()) {
            throw new RuntimeException("栈已空");
        }
        int res = helper();
        swap();
        return res;
    }
}

Dogs and Cats queue problems

The classic problem, not repeat them here. The idea is that the Pet class packaged, time-stamped, added a variable count.

class PetEntry {
    private Pet pet;
    private long count;

    public PetEntry(Pet pet, long count) {
        this.pet = pet;
        this.count = count;
    }

    public Pet getPet() {
        return this.pet;
    }

    public long getCount() {
        return this.count;
    }

    public String getEntryPetType() {
        return this.pet.getPetType();
    }
}

One obtained is then added to the queue objects PetEntry, will make a judgment on the type of the object PetEntry when added, if the class is entered Cat catQ, if the class is Dog proceeds dogQ.

public class DogCatQueue {
    private Queue<PetEntry> dogQ;
    private Queue<PetEntry> catQ;
    private long count;

    public DogCatQueue() {
        this.dogQ = new LinkedList<>();
        this.catQ = new LinkedList<>();
        this.count = 0;
    }

    public void add(Pet pet) {
        if (pet.getPetType().equals("dog")) {
            this.dogQ.offer(new PetEntry(pet, this.count++));
        } else if (pet.getPetType().equals("cat")) {
            this.catQ.offer(new PetEntry(pet, this.count++));
        } else {
            throw new RuntimeException("宠物需为猫或狗");
        }
    }

    public Pet pollAll() {
        if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) {
            if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) {
                return this.dogQ.poll().getPet();
            } else {
                return this.catQ.poll().getPet();
            }
        } else if (this.dogQ.isEmpty()) {
            return this.catQ.poll().getPet();
        } else if (this.catQ.isEmpty()) {
            return this.dogQ.poll().getPet();
        } else {
            throw new RuntimeException("队列已空!");
        }
    }

    public Dog pollDog() {
        if (this.dogQ.isEmpty()) {
            throw new RuntimeException("狗队列为空!");
        }
        return (Dog) this.dogQ.poll().getPet();
    }

    public Cat pollCat() {
        if (this.catQ.isEmpty()) {
            throw new RuntimeException("猫队列为空!");
        }
        return (Cat) this.catQ.poll().getPet();
    }

    public boolean isEmpty() {
        return this.dogQ.isEmpty() && this.catQ.isEmpty();
    }

    public boolean isDogQueueEmpty() {
        return this.dogQ.isEmpty();
    }

    public boolean isCatQueueEmpty() {
        return this.catQ.isEmpty();
    }
}

Strictly speaking this is not an arithmetic problem, but an engineering problem, we use the Decorator design pattern, like the original packaging, Entry into a class.

Guess you like

Origin www.cnblogs.com/chenxianbin/p/11918965.html