//实现一个最小栈【力扣155】
//题目:设计一个支出push,pop,top(peek) 操作,并能在常数时间内检索到最小元素的栈
/*逻辑
push
1.普通栈当中一定要放的,最小栈当中放不放? 取决于当前元素X有没有最小栈的栈顶元素小
2.如果要存放的值为X,最小栈的栈顶元素时Y
X<Y 放, X==Y 放且必须放, X>Y 不放
*/
public class MinStack {
private Stack<Integer> stack1;
private Stack<Integer> minStack;
public MinStack(){
stack1 = new Stack<>();
minStack = new Stack<>();
}
public void push(int val){
stack1.push(val);
if (minStack.empty()){
minStack.push(val);
}else {
int x = minStack.peek();
if (val <= x){
minStack.push(val);
}
}
}
public void pop(){
if (!stack1.empty()){
int x = stack1.pop();
if(x == minStack.peek()){
minStack.pop();
}
}
}
//只针对 普通栈来说的 获取普通栈的栈顶元素 相当于peek函数
public int top(){
if (!stack1.empty()){
return stack1.peek();
}
return -1;//不要抛出异常
}
public int getMin(){
if (minStack.empty()){
return -1;
}
return minStack.peek();
}
}
2.环形队列
//环形队列【力扣622】
public class MyCircularQueue {
private int[] elem;
public int front;//队头
public int rear;//队尾
public MyCircularQueue(int k){
elem = new int[k+1];
}
//入队列
public boolean enQueue(int value){
if (isFull()){
return false;
}
elem[rear] = value;
rear = (rear + 1) % elem.length;
return true;
}
//浪费一个空间判断满
public boolean isFull(){
if ((rear + 1) % elem.length == front){
return true;
}
return false;
}
//出队列
public boolean deQueue(){
if (isEmpty()){
return false;
}
front = (front + 1) % elem.length;
return true;
}
public boolean isEmpty(){
if (front == rear){
return true;
}
return false;
}
//获取队头元素
public int Front(){
if (isEmpty()){
return -1;
}
return elem[front];
}
//获取队尾元素
public int Rear(){
if (isEmpty()){
return -1;
}
int index = rear == 0 ? elem.length-1 : rear-1;
return elem[index];
}
}
3.用栈实现队列
public class MyDeQueue {
//用栈实现队列
//栈需要两个
//1.入队:直接放到第一个栈当中
//2.出第二个栈当中的数据,如果第二个栈没有数据,那么就把第一个栈当中,所有数据倒入第二个栈
private Stack<Integer> s1;
private Stack<Integer> s2;
public MyDeQueue(){
s1 = new Stack<>();
s2 = new Stack<>();
}
public void push(int x){
s1.push(x);
}
public int pop(){
if (empty()){
return -1;
}
if (s2.empty()){
while (!s1.empty()){
s2.push(s1.pop());
}
}
return s2.pop();
}
public int peek(){
if (empty()){
return -1;
}
if (s2.empty()){
while (!s1.empty()){
s2.push(s1.pop());
}
}
return s2.peek();
}
//如果两个栈都是空 那么队列就是空
public boolean empty(){
return s1.empty() && s2.empty();
}
}
4.用队列实现栈
public class MyDeStack {
//1.用队列实现栈【力扣225】
//使用两个队列实现一个栈
//思路
//入栈:入到不为空的队列当中
//出栈:就是找到不为空的队列,出size-1个元素到另一个队列当中去
private Queue<Integer> qu1;
private Queue<Integer> qu2;
public MyDeStack(){
qu1 = new LinkedList<>();
qu2 = new LinkedList<>();
}
public void push(int x){
if (qu1.isEmpty()){
qu1.offer(x);
}else if (qu2.isEmpty()){
qu2.offer(x);
}else {
//两个队列都为空的时候
qu1.offer(x);
}
}
public int pop(){
if (empty()){
return -1;
}
if (!qu1.isEmpty()){
int size = qu1.size();
for (int i = 0; i < size-1; i++) {
qu2.offer(qu1.poll());
}
return qu1.poll();
}else {
int size = qu2.size();
for (int i = 0; i < size-1; i++) {
qu1.offer(qu2.poll());
}
return qu2.poll();
}
}
//peek 获取栈顶元素
public int top(){
if (empty()){
return -1;
}
if (!qu1.isEmpty()){
int size = qu1.size();
int ret = -1;
for (int i = 0; i < size; i++) {
ret = qu1.poll();
qu2.offer(ret);
}
return ret;
}else {
int size = qu2.size();
int ret = -1;
for (int i = 0; i < size; i++) {
ret = qu2.poll();
qu1.offer(ret);
}
return ret;
}
}
//两个队列都为空,那么就是栈空
public boolean empty(){
return qu1.isEmpty() && qu2.isEmpty();
}
}