算法打卡第一天
剑指 Offer 09. 用两个栈实现队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
理解题意:
- CQueue 为要实现的队列,描述中用两个栈实现一个队列,所以需要初始化两个栈,一个负责存储加入的数据stack1,一个负责删除的数据stack2
- appendTail 函数为队列插入数据,stack1为负责存储加入的数据,所以只需要push() 就行
- deleteHead 负责删除队列头部数据, 因为队列是先进先出的,而栈是先进后出原则。删除时需要考虑一下几种情况 (1) stack1和stack2都为空,即还没加入数据就执行删除,返回-1 (2) stack1不为空,先将 stack2为空。先将stack1的所有数据push进stack2中 (3) stack1不为空,先将 stack2不为空。直接返回stack2出栈结果 (4) stack1为空,先将 stack2不为空。直接返回stack2出栈结果 特别需要注意的是第二步,我就犯了一个错,没有将stack1中所有的数据入栈stack1中,导致出栈顺序不对 解法1 如上 (超过时间:82.7%,内存:52.3%) 解法2 解法前两步都相同,最后一步顺序不同 (超过时间:55%,内存:66%) (1) stack1不为空,先将 stack2为空。先将stack1的所有数据push进stack2中 (2) stack2为空,stack1不为空,即还没加入数据就执行删除,返回-1 (3) stack2为空,stack1为空,即还没加入数据就执行删除,返回-1 (4) stack1为空,先将stack2不为空。直接返回stack2出栈结果
总结: stack1 永远负责入栈 stack2 永远负责出栈 stack2 stack2没有数据,要把stack1中的所有数据都放入2;有数据先出,stack2就只出栈就行
var CQueue = function() {
this.stack1=[]
this.stack2=[]
};
/**
* @param {number} value
* @return {void}
*/
CQueue.prototype.appendTail = function(value) {
this.stack1.push(value)
};
/**
* @return {number}
*/
CQueue.prototype.deleteHead = function() {
// 解法1
if(!this.stack1.length && !this.stack2.length){
return -1;
}
if(!this.stack2.length){
while (this.stack1.length) {
this.stack2.push(this.stack1.pop())
}
}
return this.stack2.pop();
// 解法2
// if(!this.stack2.length && this.stack1.length){
// while (this.stack1.length) {
// this.stack2.push(this.stack1.pop())
// }
// }
// if(!this.stack2.length){
// return -1;
// }else{
// return this.stack2.pop();
// }
};
// 用例1:
// 输入:
// ["CQueue","appendTail","deleteHead","deleteHead"]
// [[],[3],[],[]]
// 输出:[null,null,3,-1]
// 用例2
// 模拟实现
const a = new CQueue()
// 输入1
const arr=["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
// 输入2
const arr1=[[],[],[5],[2],[],[]]
// 运行结构
const output=[];
for (let i = 0; i < arr.length; i++) {
if(arr[i]==="CQueue"){
output.push(null)
}else if(arr[i]==="appendTail"){
a.appendTail(arr1[i])
output.push(null)
}else if(arr[i]==="deleteHead"){
const num=a.deleteHead();
output.push(Array.isArray(num)?num[0]:num)
}
}
console.log(output); // [null,-1,null,null,5,2]
剑指 Offer 30. 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
理解题意: MinStack的min方法来查找最小数 时间复杂度为1
- 定义两个栈,一个用来存储正常数据stack,一个用来存储当最小数的栈minStack
- push方法 stack正常入栈操作;在push的时候就进行比对,当前数与minStack中顶部数比较,存储较小值
- pop方法 stack和minStack正常出栈
- top方法 返回stack栈顶元素
- min方法 返回minStack栈顶元素
此方法超过执行时间超过99%
/**
* initialize your data structure here.
*/
var MinStack = function() {
this.stack = []
this.minStack = []
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
this.stack.push(x)
if(this.minStack.length){
this.minStack.push(Math.min(this.minStack[this.minStack.length-1],x))
return
}
this.minStack.push(x)
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
this.stack.pop()
this.minStack.pop()
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this.stack[this.stack.length - 1]
};
/**
* @return {number}
*/
MinStack.prototype.min = function() {
if(!this.minStack.length){
return -1
}
return this.minStack[this.minStack.length-1]
};