232.用栈实现队列(JS)

1,941 阅读2分钟

用栈实现队列

Category Difficulty Likes Dislikes
algorithms Easy (60.75%) 89 -
Tags
Companies
使用栈实现队列的下列操作:
  • push(x) -- 将一个元素放入队列的尾部。
  • pop() -- 从队列首部移除元素。
  • peek() -- 返回队列首部的元素。
  • empty() -- 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);  
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
/*
 * @lc app=leetcode.cn id=232 lang=javascript
 *
 * [232] 用栈实现队列
 */
/**
 * Initialize your data structure here.
 */
var MyQueue = function() {

};

/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {

};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function() {

};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function() {

};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {

};

/** 
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */


1 基本概念

首先这道题真的是很无聊,主要是考察对栈和队列性质的认知

image-20190808165954045

栈的操作就像我们对这堆盘子的操作是一样的

我们只能在

  • 栈顶添加元素push
  • 查看栈顶元素peek
  • 取出栈顶元素pop
  • 检查是否为口empty

队列

image-20190808170443155

就更简单了就是简单的先来后到

  • 添加新元素只能在原队伍的最后面添加push
  • 查看元素也是查看最前面的一位peek
  • 离开队伍也是最前面一位pop
  • 检查队列是否为空empty

2 代码实现

栈的顺序是先进后出

队列的顺序是先进先出

所以如果我们只有一个栈是不可能模拟出队列的效果的

于是我们使用两个栈

image-20190808191958681

MyQueue.prototype.pop = function () {
  const tempStack = []
  for (let i = 0; i < this.stack.length; i++) {
    tempStack.push(this.stack.pop())
  }
  const ret = tempStack.pop()
  for (let j = 0; j < tempStack.length; j++) {
    this.stack.push(tempStack.pop())
  }
  return ret
};

上面的这种写法是错误的,也是大家很容易忽略的:数组塌陷

每次循环的时候,因为我们对this.stack.pop(),这个操作是会影响this.stack.length,那在进行下次循环时,这个值就已经改变了,这和我们的本意有差

MyQueue.prototype.pop = function () {
	const tempStack = []
	while (this.stack.length) {
		tempStack.push(this.stack.pop())
	}
	const ret = tempStack.pop()
	while (tempStack.length) {
		this.stack.push(tempStack.pop())
	}
	return ret
};

那其他的方法就很容易实现了

/*
 * @lc app=leetcode.cn id=232 lang=javascript
 *
 * [232] 用栈实现队列
 */
/**
 * Initialize your data structure here.
 */
var MyQueue = function () {
	this.stack = []
};

/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function (x) {
	this.stack.push(x)
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function () {
	const tempStack = []
	while (this.stack.length) {
		tempStack.push(this.stack.pop())
	}
	const ret = tempStack.pop()
	while (tempStack.length) {
		this.stack.push(tempStack.pop())
	}
	return ret
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function () {
	return this.stack[0]
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
	return this.stack.length === 0
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */