20. 有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
输入: s = "()[]{}"
输出: true
[ '(' ]
[]
[ '[' ]
[]
[ '{' ]
[]
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
let map = {'{':'}','(':')','[':']'};
let stack = [];
for(let i of s){
if(map[i]){
stack.push(i);
}else{
if(map[stack[stack.length - 1]] === i){
stack.pop();
}else{
return false;
}
}
console.info(stack);
}
return stack.length === 0;
};
155. 最小栈
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
最小栈打印结果:
[ -2 ]
[ -2, -2 ]
[ -2, -2, -3 ]
/**
* initialize your data structure here.
*/
var MinStack = function() {
this.stack = [];
this.minStack = [];
};
/**
* @param {number} val
* @return {void}
*/
MinStack.prototype.push = function(val) {
this.stack.push(val);
let topOfMinStack = this.minStack[this.minStack.length - 1];
if(this.minStack.length === 0 || val < topOfMinStack){
this.minStack.push(val);
} else {
this.minStack.push(topOfMinStack);
}
console.info(this.minStack);
};
/**
* @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.getMin = function() {
return this.minStack[this.minStack.length - 1];
};
/**
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(val)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.getMin()
*/
739. 每日温度
请根据每日 气温
列表 temperatures
,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0
来代替。
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
出栈 stack的值 stack res
[ 73 ] [ 0 ] [ 0, 0, 0, 0, 0, 0, 0, 0 ]
1-0 [ 74 ] [ 1 ] [ 1, 0, 0, 0, 0, 0, 0, 0 ]
2-1 [ 75 ] [ 2 ] [ 1, 1, 0, 0, 0, 0, 0, 0 ]
[ 75, 71 ] [ 2, 3 ] [ 1, 1, 0, 0, 0, 0, 0, 0 ]
[ 75, 71, 69 ] [ 2, 3, 4 ] [ 1, 1, 0, 0, 0, 0, 0, 0 ]
5-4 5-3 [ 75, 72 ] [ 2, 5 ] [ 1, 1, 0, 2, 1, 0, 0, 0 ]
6-5 6-2 [ 76 ] [ 6 ] [ 1, 1, 4, 2, 1, 1, 0, 0 ]
[ 76, 73 ] [ 6, 7 ] [ 1, 1, 4, 2, 1, 1, 0, 0 ]
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
let len = temperatures.length;
let res = (new Array(len)).fill(0);
let stack = [];
for(let i = 0; i < len; i++) {
while(stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {
let top = stack.pop();
console.info(i + '-' + top);
// 当前下标减去之前记录的下标
res[top] = i - top;
}
stack.push(i);
stack1.push(temperatures[i]);
console.info(stack);
console.info(res);
}
return res;
};
232. 用栈实现队列
用栈先进后出
的方式来实现队列先进先出
的效果
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
var MyQueue = function() {
this.stack1 = []; // 用于入队
this.stack2 = []; // 用于出队
};
/**
* @param {number} x
* @return {void}
*/
MyQueue.prototype.push = function(x) {
this.stack1.push(x);
};
/**
* @return {number}
*/
MyQueue.prototype.pop = function() {
// 将入队栈中的数据导入到出队栈中
if(!this.stack2.length) {
while(this.stack1.length) {
this.stack2.push(this.stack1.pop());
}
}
return this.stack2.pop();
};
/**
* @return {number}
*/
MyQueue.prototype.peek = function() {
if(!this.stack2.length) {
while(this.stack1.length) {
this.stack2.push(this.stack1.pop());
}
}
// 跟pop相比,只是不出队
return this.stack2[this.stack2.length - 1];
};
/**
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
// 入队栈和出队栈都为空时,队列为空
return !this.stack1.length && !this.stack2.length;
};
/**
* 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()
*/
225. 用队列实现栈
用队列先进先出
的方式来实现栈先进后出
的效果
一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时在去弹出元素就是栈的顺序了。
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
/**
* Initialize your data structure here.
*/
var MyStack = function() {
this.queue = [];
};
/**
* Push element x onto stack.
* @param {number} x
* @return {void}
*/
MyStack.prototype.push = function(x) {
this.queue.push(x);
};
/**
* Removes the element on top of the stack and returns that element.
* @return {number}
*/
MyStack.prototype.pop = function() {
let size = this.queue.length;
while(size-- > 1) {
this.queue.push(this.queue.shift());
}
return this.queue.shift();
};
/**
* Get the top element.
* @return {number}
*/
MyStack.prototype.top = function() {
const x = this.pop();
this.queue.push(x);
return x;
};
/**
* Returns whether the stack is empty.
* @return {boolean}
*/
MyStack.prototype.empty = function() {
return !this.queue.length;
};
/**
* Your MyStack object will be instantiated and called as such:
* var obj = new MyStack()
* obj.push(x)
* var param_2 = obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.empty()
*/
239. 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
窗口最开始从0扩张到k后,之后就一直维持k的大小,一步一步往后移,直到无法移动为止
i+1>=k window window对应的nums值
f [ 0 ] [ 1 ]
f [ 1 ] [ 3 ]
t [ 1, 2 ] [ 3, -1 ]
t [ 1, 2, 3 ] [ 3, -1, -3 ]
t [ 4 ] [ 5 ]
t [ 4, 5 ] [ 5, 3 ]
t [ 6 ] [ 6 ]
t [ 7 ] [ 7 ]
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
let window = [];
let res = [];
for(let i = 0; i < nums.length; i++) {
// 先把滑动窗口之外的踢出
if(window[0] !== undefined && window[0] <= i - k) window.shift();
// 保证队首是最大的
while(nums[window[window.length - 1]] <= nums[i]) window.pop();
window.push(i);
if(i + 1 >= k) res.push(nums[window[0]]);
console.info(window);
}
return res;
};