设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
思路:用两个栈实现,一个普通栈和一个最小栈,最小栈和普通栈同步操作,当push操作时,最小栈push min(最小栈顶,x)
/**
* initialize your data structure here.
*/
var MinStack = function() {
this._stack = [];
this._minStack = [Infinity];
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
this._stack.push(x);
this._minStack.push(Math.min(this._minStack[this._minStack.length-1],x));
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
this._minStack.pop()
this._stack.pop();
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this._stack[this._stack.length -1];
};
/**
* @return {number}
*/
MinStack.prototype.getMin = function() {
return this._minStack[this._minStack.length - 1];
};
波兰表达式计算 > 输入:
["2", "1", "+", "3", "*"]
> 输出: 9解释:
((2 + 1) * 3) = 9
思路:通过栈保存原来的元素,遇到表达式弹出运算,再推入结果,重复这个过程
var evalRPN = function(tokens) {
var stack = [];
while(tokens.length > 0){
let val = tokens.shift();
if(val === '+' || val === '-' || val === '*' || val === '/'){
let b = stack.pop();
let a = stack.pop();
switch(val){
case '+':
stack.push(a+b)
break
case "*":
stack.push(a*b)
break
case "-":
stack.push(a-b)
break
case "/":
stack.push(a/b > 0 ? Math.floor(a/b) : Math.ceil(a/b));
break
}
}
else{
val = parseInt(val);
stack.push(val);
}
}
return stack[0]
};
给定一个经过编码的字符串,返回它解码后的字符串。 s = "3[a]2[bc]", 返回 "aaabcbc". s = "3[a2[c]]", 返回 "accaccacc". s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
思路:通过栈辅助进行操作
const decodeString = (s) => {
let numStack = [] // 存 倍数num 的栈
let strStack = [] // 存 待拼接的str 的栈
let num = 0 // 倍数的“搬运工”
let result = '' // 字符串的“搬运工”
for (const char of s) { // 逐字符扫描
if (!isNaN(char)) { // 遇到数字
num = num * 10 + Number(char) // 读取数字
} else if (char === '[') { // 遇到 [
strStack.push(result) // result串进入strStack栈等待
result = '' // 完成进栈后 清零
numStack.push(num) // 倍数num进入栈等待
num = 0 // 完成进栈后 清零
} else if (char === ']') { // 遇到 ],两个栈的栈顶出栈
let repeatTimes = numStack.pop() // 获取拷贝次数
result = strStack.pop() + result.repeat(repeatTimes) // 构建子串
} else { // 遇到字母,追加给result串
result += char
}
}
return result
}
给你无向连通图中一个节点的引用,请你返回该图的深拷贝(克隆)。
var cloneGraph = function(node) {
var map = new Map();
function deepCopy(node){
if(node == null) return null;
// 如果有已经访问过该节点,直接返回
if(map.has(node.val)){
return map.get(node.val);
}
// 复制node
var cloneNode = new Node(node.val,[]);
// 加入map
map.set(cloneNode.val,cloneNode);
for (let k of node.neighbors){
const neighborNodes = deepCopy(k);
cloneNode.neighbors.push(neighborNodes);
}
return cloneNode;
}
return deepCopy(node);
};
- Queue 队列
常用于 BFS 宽度优先搜索
使用栈实现队列
/**
* 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() {
let a = this.stack[0];
let temp = [];
for(let i = 1;i < this.stack.length ; i++){
temp[i-1] = this.stack[i];
}
this.stack = temp;
return a;
};
/**
* 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 ? false : true;
};
二叉树层次遍历
var levelOrder = function(root) {
var stack = [];
var queue = [];
var res = [];
if(!root) return [];
stack.push(root);
stack.push('s');
while(stack.length > 0){
var node = stack.shift();
while(node!='s'){
node.left && stack.push(node.left);
node.right && stack.push(node.right);
queue.push(node.val);
node = stack.shift();
}
res.push(queue);
queue = [];
if(stack.length > 0){
stack.push('s');
}
}
return res;
};