1.栈和队列常见方法
(1)栈:
stack.push()//压栈
stack.pop()//弹栈
stack.empty()==true//栈为空
stack.peek()//返回栈顶元素(只返回不删除)
(2)队列:
queue.add():往队尾添加元素
queue.remove():删除队头元素(并且返回队头元素)
queue.peek():返回队头元素(只返回不删除)
Queue queue=new LinkedList();
queue.add(1)
queue.add(2)
queue.add(3)
queue.add(4)
queue.add(5)
int size=queue.szie();
for(int i=0;i<size;i++)
{
Systerm.out.println(queue.remove());
//得到1,2,3,4,5
}
双端队列:
(1)队列只能在队尾添加元素,在队头删除元素,而双端队列在队头队尾都可以进行添加和删除操作
(2)双端队列Deque的常见方法:(在队列的add,peek,remove方法基础上进行改造)
//创建双端队列
Deque queue=new LinkedList();
//First表示队首,Last表示队尾
//在队首添加元素
queue.addFirst();
//在队尾增加元素
queue.addLast();
//获取队首元素
queue.peekFirst();
//获取队尾元素
queue.peekLast();
//移除并且返回队首元素
queue.removeFirst();
queue.removeLast();
2.用两个栈实现队列:力扣(剑指offer09)
把栈和队列都想象成一个黑箱子
将1,2,3依次输入到这个黑箱子,如果这个黑箱子是栈,就依次返回3,2,1
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如果这个黑箱子是队列,就依次返回1,2,3
加入元素的时候直接加入到stack1里面就行
主要是弹出元素时:弹出元素肯定是弹出stack2中的元素
如果stack2中有元素,就直接stack2.pop()
stack2为空的时候(即stack2中没有元素可以弹出的时候),把stack1中的元素全部转移到stack2中,然后再stack2.pop()
?将stack1内的元素全部转移到stack2内 :
class CQueue
{
Stack<Integer> stack1;
Stack<Integer> stack2;
public CQueue()
{
stack1=new Stack();
stack2=new Stack();
}
//往你创建的队列中添加元素
public void appendTail(int value)
{
stack1.push(value);
}
//往你创建的队列中弹出元素
public int deleteHead()
{
//要弹出元素,肯定是弹出stack2这个栈里面的栈顶元素
//如果stack2栈内元素为空,stack1内也没元素,那就返回-1
//如果stack2栈内元素为空,stack1内有元素,就把stack1内所有元素转移到stack2里面去
/*比如stack1里面添加了四个元素1,2,3,4,现在显然是想要打印出1,2,3,4
所以要把1,2,3,4全部从stack1中压入stack2中,这样不断stack2.pop()才能得到1,2,3,4*/
if(stack2.empty()==true)
{
if(stack1.empty()==true) return -1;
else//如果stack1不为空
{
while(stack1.empty()==false)
{
stack2.push(stack1.pop());
}
}
}
return stack2.pop();
}
}
//创建队列(调用构造方法)
CQueue obj = new CQueue();
//添加一个元素进队列队尾
obj.appendTail(value);
//删除队头元素并且返回这个队头元素
int param_2 = obj.deleteHead();
另外一道跟这个也很相似力扣(leetcode232)
class MyQueue
{
Stack<Integer> stack1;
Stack<Integer> stack2;
//调用构造方法创建两个栈
public MyQueue()
{
stack1=new Stack();
stack2=new Stack();
}
public void push(int x)
{
stack1.push(x);
}
public int pop()
{
//肯定是弹出stack2中的元素
//stack2为空的时候(即stack2中没有元素可以弹出的时候),把stack1中的元素全部转移到stack2中
if(stack2.empty()==true)
{
while(stack1.empty()==false)
{
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
public int peek()
{
if(stack2.empty()==true)
{
while(stack1.empty()==false)
{
stack2.push(stack1.pop());
}
}
return stack2.peek();
}
public boolean empty()
{
if(stack1.empty()==true&&stack2.empty()==true)
{
return true;
}
return false;
}
}
3.用两个队列实现栈
力扣225
定义两个队列,其中queue1队列用来加入元素,queue2队列用来peek和pop弹出元素
?
class MyStack
{
Queue<Integer> queue1;
Queue<Integer> queue2;
public MyStack()
{
queue1=new LinkedList();
queue2=new LinkedList();
}
public void push(int x)
{
//step1:先把元素添加到queue1里面
queue1.add(x);
//step2:只要队列queue2里面还有元素,就要把它转移到队列queue1里面
while(queue2.size()!=0)
{
queue1.add(queue2.remove());
}
//step3:此时元素就全部在队列queue1里面了,再交换queue1和queue2即可
Queue temp=queue1;
queue1=queue2;
queue2=temp;
}
public int pop()
{
return queue2.remove();
}
public int top()
{
return queue2.peek();
}
public boolean empty()
{
return queue2.size()==0;
}
}
4.最小栈
力扣155
最小栈其实就是在栈的基础上多了一个获取最小元素的功能
这道题进行测试时
minStack minstack=new MinStack();
minstack(-2);
minstack(0);
ninstack(-3);
//先压三个元素进栈
//然后调用getMin()方法来获取栈内最小元素是多少
minstack.getMin();
?暴力方法:
class MinStack
{
Stack<Integer>stack;
public MinStack()
{
stack=new Stack();
}
public void push(int val)
{
stack.push(val);
}
public void pop()
{
stack.pop();
}
public int top()
{
return stack.peek();
}
public int getMin()
{
ArrayList<Integer> a=new ArrayList();
for(int i:stack)
{
a.add(i);
}
int temp=Integer.MAX_VALUE;
for(int j:a)
{
temp=Math.min(temp,j);
}
return temp;
}
显然暴力法时间复杂度为O(n),因为遍历栈的时间复杂度为O(n)
题目规定要用常数时间内找到最小元素肯定是满足不了的
双栈法:用两个栈,一个栈是正常的栈,元素进栈和出栈都是正常的
另一个栈是特殊的栈,一个元素要想进这个栈必须小于这个栈的栈顶元素,
当正常栈弹出栈顶元素时,特殊栈要不要也弹出栈顶元素呢?当正常栈要弹出的栈顶元素等于特殊栈的栈顶元素时,特殊栈的栈顶元素也要弹出,不相等时,特殊栈的栈顶元素就不用弹出
class MinStack
{
Stack<Integer> stack1;
Stack<Integer> stack2;
public MinStack()//初始化两个栈,一个正常栈,一个特殊栈
{
stack1=new Stack();
stack2=new Stack();
}
public void push(int x)
{
//stack1正常栈,入栈时正常入栈就行
stack1.push(x);
if(stack2.empty()) stack2.push(x);
else
{
if(x<=stack2.peek()) stack2.push(x);
}
}
public void pop()
{
int temp=stack1.peek();
stack1.pop();
if(!stack2.empty()&&stack2.peek()==temp) stack2.pop();
}
public int top()
{
return stack1.peek();
}
public int getMin()
{
return stack2.peek();
}
}
|