「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」
前言
我们到知道队列是先进先出,栈是先入后出,这两种数据结构其实我们Javascript中都不是直接存在,都需要模拟出来,所以,我说明了一下你是不是迷糊了,栈可以用数组,但只能用模拟栈操作的push和pop操作来模拟队列哟!
题目描述
面试题 03.04. 化栈为队
实现一个MyQueue类,该类用两个栈来实现一个队列。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/im… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 首先选好
模拟栈的数据结构,就是数组stackArr,而且根据题目的说明我们只能用数组的push和pop操作,因为栈是先入后出,pop是从栈开始pop的,最先一个push进去的最后一个pop出来,这是队栈的模拟; - 模拟队列用一个数组肯定是不够的,因为队列是先入先出,栈是先入后出,我们只能从栈顶开始pop,这个时候我们
还需要一个辅助数组tempStackArr,这个时候我们就可以来分解队列的两步操作了,用stackArr来作为队列的入队操作,tempStackArr做出队操作:- push操作
队列执行push操作我们直接push到stackArr中即可 - pop操作
1) 如果tempStackArr中没有数据,且stackArr中也没有数据,说明队列是空的,返回false;
2) 如果tempStackArr中没有数据stackArr中有数据,我们就把stackArr中的数据全都pop到tempStackArr,这样tempStackArr中栈顶元素就是第一个push到stackArr中的元素了,这个时候我们对tempStackArr执行pop即可;
3) 如果tempStackArr中有数据我们就不用看stackArr了,直接对tempStackArr执行pop,因为tempStackArr中的数据是先入队的元素,只有stack进了之后才有可能进到tempStackArr中.
- push操作
开始解题
/**
* 题设我们所有操作都是有效的,执行push、pop操作时不用考虑队列满和空的状况
*/
var MyQueue = function() {
// 队列初始化构建需要两个空栈
this.stackArr = [];
this.tempStackArr = [];
};
MyQueue.prototype.push = function(x) {
this.stackArr.push(x); // 入队操作直接push到stackArr中,无需返回值
};
/**
* 出队队首元素并返回
* @return {number}
*/
MyQueue.prototype.pop = function() {
if(!this.tempStackArr.length) { // 如果tempStackArr为空了就把stackArr中的元素pop到tempStackArr中
while(this.stackArr.length) {
this.tempStackArr.push(this.stackArr.pop());
}
}
return this.tempStackArr.pop();
};
/**
* 只返回队首元素不执行出队操作
* @return {number}
*/
MyQueue.prototype.peek = function() {
if(!this.tempStackArr.length) {
while(this.stackArr.length) {
this.tempStackArr.push(this.stackArr.pop());
}
}
let result = this.tempStackArr.pop(); // 先拿到队首的值存起来,再push回去
this.tempStackArr.push(result);
return result;
};
/**
* 如果队列为空返回false
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
return !stackArr.length && ! tempStackArr.length;
};