// 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
// 实现 MinStack 类:
// MinStack() 初始化堆栈对象。
// void push(int val) 将元素val推入堆栈。
// void pop() 删除堆栈顶部的元素。
// int top() 获取堆栈顶部的元素。
// int getMin() 获取堆栈中的最小元素。
class MinStack {
constructor() {
this.stackA = [];
this.countA = 0;
}
// input stack
push(item) {
this.stackA[this.countA] = item;
this.countA++;
}
// output stack
pop() {
if (this.isEmpty()) {
return;
}
const value = this.top();
this.countA--;
return value;
}
top() {
return this.stackA[this.countA - 1];
}
isEmpty() {
return this.countA === 0;
}
// min
getMin() {
console.log(this.stackA)
return Math.min(...this.stackA.slice(0, this.countA));
}
}
const minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
const top1 = minStack.getMin(); // --> 返回 -3.
console.log("top1: ", top1);
minStack.pop();
const top2 = minStack.top(); // --> 返回 0.
console.log("top2: ", top2);
const top3 = minStack.getMin(); // --> 返回 -2.
console.log("top3: ", top3);
LeetCode的执行时间比较高 500ms,感觉是下面的代码用时多
getMin() {
console.log(this.stackA)
return Math.min(...this.stackA.slice(0, this.countA));
}
class MinStack {
constructor() {
this.stackA = [];
this.countA = 0;
}
// input stack
push(item) {
this.stackA[this.countA] = item;
this.countA++;
}
// output stack
pop() {
if (this.isEmpty()) {
return;
}
const value = this.top();
this.stackA.length--;
this.countA--;
return value;
}
top() {
return this.stackA[this.countA - 1];
}
isEmpty() {
return this.countA === 0;
}
// min
getMin() {
return Math.min.apply(null, this.stackA);
}
}
const minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
const top1 = minStack.getMin(); // --> 返回 -3.
console.log("top1: ", top1);
minStack.pop();
const top2 = minStack.top(); // --> 返回 0.
console.log("top2: ", top2);
const top3 = minStack.getMin(); // --> 返回 -2.
console.log("top3: ", top3);
LeetCode的执行时间还是比较高 200ms
上面的代码几乎没有用原生的方法,于是想着用js原生方法,看一看能不能有改善
class MinStack {
constructor() {
this.stackA = [];
}
// input stack
push(item) {
this.stackA[this.stackA.length] = item;
}
// output stack
pop() {
if (this.isEmpty()) {
return;
}
return this.stackA.pop();
}
top() {
return this.stackA[this.stackA.length - 1];
}
isEmpty() {
return this.stackA.length === 0;
}
// min
getMin() {
return Math.min.apply(null,this.stackA);
}
}
还是200ms,这种思路就不行,数组中取最小值,太浪费时间,想到了取巧的方式,就是之前写过的[双数组的方法](https://blog.csdn.net/Martin164/article/details/124680655)
思考过程:
最短时间获取到最小值,就需要把最小值存起来,一种就是上面的双数组方法,把最小值放入另一个数组中,同理,可以把最小值放入每个类似链表的节点上,这里就是一个对象,每次添加值的时候,添加一个对象,这个对象包含当前值和最小值
class MinStack {
constructor() {
this.stackA = [];
}
// input stack
push(item) {
if (this.isEmpty()) {
this.stackA[this.stackA.length] = {
value: item,
min: item
}
}else {
if (item > this.stackA[this.stackA.length - 1].min) {
this.stackA[this.stackA.length] = {
value: item,
min: this.stackA[this.stackA.length - 1].min,
};
} else {
this.stackA[this.stackA.length] = {
value: item,
min: item,
};
}
}
}
// output stack
pop() {
if (this.isEmpty()) {
return;
}
return this.stackA.pop().value;
}
top() {
return this.stackA[this.stackA.length - 1].value;
}
isEmpty() {
return this.stackA.length === 0;
}
// min
getMin() {
return this.stackA[this.stackA.length - 1].min;
}
}
上面的代码写的繁琐了 提交leetcode 100ms,主要是按照下意识的思路写的,也比较方便理解过程,优化一下:
class MinStack {
constructor() {
this.stackA = [];
}
// input stack
push(item) {
// 获取当前的最小值
const minValue =
(this.isEmpty() || item <= this.stackA[this.stackA.length - 1].min)
? item
: this.stackA[this.stackA.length - 1].min;
this.stackA[this.stackA.length] = {
value: item,
min: minValue,
};
}
// output stack
pop() {
if (this.isEmpty()) {
return;
}
return this.stackA.pop().value;
}
top() {
return this.stackA[this.stackA.length - 1].value;
}
isEmpty() {
return this.stackA.length === 0;
}
// min
getMin() {
return this.stackA[this.stackA.length - 1].min;
}
}
执行时间84ms,比较满意,抽空去LeetCode看看大神的方法。