栈:先入后出
这里设置的是固定长度的栈,而不是变长的栈;
除了准备size以外,还应有个index指示,该指示标志的是新来的数放置的位置。
public class Code_01_Array_To_Stack_Queue {
public static class ArrayStack {
private Integer[] arr;
private Integer index;
//新建数据时,需要确定数组开多大
public ArrayStack(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("The init size is less than 0");
}
arr = new Integer[initSize];
index = 0;
}
public Integer peek() {
if (index == 0) {
return null;
}
return arr[index - 1];
}
public void push(int obj) {
if (index == arr.length) { //判断满了没
throw new ArrayIndexOutOfBoundsException("The queue is full");
}
arr[index++] = obj;
}
public Integer pop() {
if (index == 0) {
throw new ArrayIndexOutOfBoundsException("The queue is empty");
}
return arr[--index];
}
}
类似于fifo
先入先出
size 约束first和last指针
数组是循环利用的,判断空满只需要判断size的值即可
public static class ArrayQueue {
private Integer[] arr;
private Integer size;
private Integer first;
private Integer last;
public ArrayQueue(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("The init size is less than 0");
}
arr = new Integer[initSize];
size = 0; //一开始都指向0
first = 0;
last = 0;
}
public Integer peek() { //返回第一个值
if (size == 0) {
return null;
}
return arr[first];
}
public void push(int obj) { //入栈操作 如果栈满就丢异常
if (size == arr.length) {
throw new ArrayIndexOutOfBoundsException("The queue is full");
}
size++; //否则size++
arr[last] = obj;
//如果last已经到底,就会回到0位置,循环利用 只要size没超就行
last = last == arr.length - 1 ? 0 : last + 1;
}
public Integer poll() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("The queue is empty");
}
size--;
int tmp = first;
first = first == arr.length - 1 ? 0 : first + 1;
return arr[tmp];
}
}
在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。
【要求】
1.pop、push、getMin操作的时间复杂度都是O(1)。
2.设计的栈类型可以使用现成的栈结构。
这里主要是要求getMin的时间复杂度为O(1),所以考虑牺牲额外空间复杂度
代码如下:
public static class MyStack2 {
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack2() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
public void push(int newNum) { //压栈操作
if (this.stackMin.isEmpty()) { //这几个判断都是判断min栈放入什么数
this.stackMin.push(newNum);
} else if (newNum < this.getmin()) { //如果data栈的数小于min栈顶,则压入data栈的数
this.stackMin.push(newNum);
} else {
int newMin = this.stackMin.peek(); //min栈顶再压一次
this.stackMin.push(newMin);
}
this.stackData.push(newNum);
}
public int pop() { //同时出栈
if (this.stackData.isEmpty()) {
throw new RuntimeException("Your stack is empty.");
}
this.stackMin.pop();
return this.stackData.pop();
}
public int getmin() {
if (this.stackMin.isEmpty()) {
throw new RuntimeException("Your stack is empty.");
}
return this.stackMin.peek();
}
}
例如:5、4、3、2、1----5+4321----321+4-----3+21
public static class TwoQueuesStack {
private Queue<Integer> data; //数据进入的队列
private Queue<Integer> help; //数据输出的队列
public TwoQueuesStack() {
data = new LinkedList<Integer>();
help = new LinkedList<Integer>();
}
public void push(int pushInt) {
data.add(pushInt); //所有的输入数据只存放在当前的进入队列中
}
public int peek() { //查看栈顶的数
if (data.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
while (data.size() != 1) { //这一步和下面的pop意义一样
help.add(data.poll());
}
int res = data.poll();
help.add(res); //区别在这里,返回的结果也会重新放到help中去,不会弹出
swap();
return res;
}
public int pop() { //弹出
if (data.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
while (data.size() > 1) { //除了最后一个数,data队列中的所有数输入到help队列里
help.add(data.poll());
}
int res = data.poll(); //直到最后一个数输出
swap(); //交换两个队列的索引
return res;
}
private void swap() {
Queue<Integer> tmp = help;
help = data;
data = tmp;
}
}
代码如下: 好理解
public static class TwoStacksQueue {
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStacksQueue() {
stackPush = new Stack<Integer>();
stackPop = new Stack<Integer>();
}
public void push(int pushInt) {
stackPush.push(pushInt);
}
public int poll() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.pop(); //之前的判断和循环主要是为了确保pop栈里的正确
}
public int peek() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.peek();
}
}
public static class Pet {
private String type;
public Pet(String type) {
this.type = type;
}
public String getPetType() {
return this.type;
}
}
public static class Dog extends Pet {
public Dog() {
super("dog");
}
}
public static class Cat extends Pet {
public Cat() {
super("cat");
}
}
public static class PetEnterQueue {
private Pet pet;
private long count;
public PetEnterQueue(Pet pet, long count) {
this.pet = pet;
this.count = count;
}
public Pet getPet() {
return this.pet;
}
public long getCount() {
return this.count;
}
public String getEnterPetType() {
return this.pet.getPetType();
}
}
public static class DogCatQueue {
private Queue<PetEnterQueue> dogQ;
private Queue<PetEnterQueue> catQ;
private long count;
public DogCatQueue() {
this.dogQ = new LinkedList<PetEnterQueue>();
this.catQ = new LinkedList<PetEnterQueue>();
this.count = 0;
}
public void add(Pet pet) {
if (pet.getPetType().equals("dog")) {
this.dogQ.add(new PetEnterQueue(pet, this.count++));
} else if (pet.getPetType().equals("cat")) {
this.catQ.add(new PetEnterQueue(pet, this.count++));
} else {
throw new RuntimeException("err, not dog or cat");
}
}
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.dogQ.poll().getPet();
} else if (!this.catQ.isEmpty()) {
return this.catQ.poll().getPet();
} else {
throw new RuntimeException("err, queue is empty!");
}
}
public Dog pollDog() {
if (!this.isDogQueueEmpty()) {
return (Dog) this.dogQ.poll().getPet();
} else {
throw new RuntimeException("Dog queue is empty!");
}
}
public Cat pollCat() {
if (!this.isCatQueueEmpty()) {
return (Cat) this.catQ.poll().getPet();
} else
throw new RuntimeException("Cat queue is empty!");
}
public boolean isEmpty() {
return this.dogQ.isEmpty() && this.catQ.isEmpty();
}
public boolean isDogQueueEmpty() {
return this.dogQ.isEmpty();
}
public boolean isCatQueueEmpty() {
return this.catQ.isEmpty();
}
}
可以重点留意下取出的判断条件,别的较简单