文章目录
哈喽,我是长路,目前刚刚大三,方向是后端也偶尔捣鼓下前端,现在的主语言是Java。之前一大段时间都是在学习web开发的一些技术,就很久没有进行类似于数据结构、算法之类的学习与刷题,打算这段时间拾起来好好学一学、搞一搞。
这段时间也是机缘巧合看到草帽路飞的博客,加了自学群,正巧看到博主组织在群里组织了leetcode刷题打卡活动,我也就参与进来,为期一个月,打算坚持每天都花一些时间做一些题目,并通过博客的方式来进行记录。
目前跟着一个Github仓库刷题(leetcode):代码随想录leetcode刷题,当前为栈与队列专题。
题目
题目来源leetcode
leetcode地址:225. 用队列实现栈,难度:简单。
题目描述(摘自leetcode):
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
提示:
1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空
进阶:你能否实现每种操作的均摊时间复杂度为 O(1) 的栈?换句话说,执行 n 个操作的总时间复杂度 O(n) ,尽管其中某个操作可能需要比其他操作更长的时间。你可以使用两个以上的队列。
本地调试代码:
class MyStack {
public MyStack() {
}
public void push(int x) {
}
public int pop() {
}
public int top() {
}
public boolean empty() {
}
public static void main(String[] args) {
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.push(3);
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
}
}
题解
NO1:两个单队列实现
思路: 两个队列,出队通过队列1来进行。每插入一个元素,先插入到队列2,接着将队列1中的元素全部插入到队列2,接着队列1与队列2进行互换。之后重复操作。
①插入1
队列1:[] 队列2:[1]
队列1:[1] 队列2:[]
②插入2
队列1:[1] 队列2:[2]
队列1:[] 队列2:[1,2]
队列1:[1,2] 队列2:[]
此时出队列顺序先是2,接着是1,此时就实现了栈。
代码:
class MyStack {
private Queue<Integer> queue1;
private Queue<Integer> queue2;//辅助队列,入队是先存储到该队列
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);
//将原本队列1中的内容进行存储到队列2(构成栈)
while (!queue1.isEmpty()) {
queue2.offer(queue1.poll());
}
//交换queue1与queue2,因为之后使用的是queue1来进行出队
Queue<Integer> tempQueue = queue1;
queue1 = queue2;
queue2 = tempQueue;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
NO2:一个双端队列实现
思路:用一个双端队列来实现
每push一个数据就添加到队头,如下:
①添加1 [1]
②添加2 [1,2]
③添加3 [1,2,3]
之后pop出数据每次从队头获取
① pop() 取出3 [1,2]
② pop() 取出2 [1]
③ pop() 取出1 []
这样的添加与取方式就已经构成了栈的形式
代码:
class MyStack {
//定义一个双端队列
private Deque<Integer> queue;
public MyStack() {
queue = new ArrayDeque<>();
}
public void push(int x) {
queue.offerFirst(x);//添加到队头
}
public int pop() {
return queue.pollFirst();//出队头
}
public int top() {
return queue.peekFirst();//打印队头数据
}
public boolean empty() {
return queue.isEmpty();
}
}
参考文章
[1]. leetcode题解
[2]. 代码随想录— 225. 用队列实现栈
我是长路,感谢你的耐心阅读。如有问题请指出,我会积极采纳!
欢迎关注我的公众号【长路Java】,分享Java学习文章及相关资料
Q群:851968786 我们可以一起探讨学习
注明:转载可,需要附带上文章链接