20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
示例 1:
- 输入: "()"
- 输出: true
示例 2:
- 输入: "()[]{}"
- 输出: true
示例 3:
- 输入: "(]"
- 输出: false
核心:用「栈」的先进后出特性,匹配成对括号
-
准备一个空栈,专门存待匹配的右括号
-
遍历字符串:
- 碰到左括号
([{,就把对应的右括号压进栈 - 碰到右括号,就弹出栈顶的括号对比,不匹配直接判定无效
- 碰到左括号
-
遍历结束后,栈为空 就是有效括号,否则无效
var isValid = function(s) {
let Stack =[]
for(let i=0;i<s.length;i++){
let c = s[i];
switch(c){
case "(":Stack.push(")") ;break;
case "[":Stack.push("]") ;break;
case "{":Stack.push("}") ;break;
default:
if(c!=Stack.pop()){
return false
}
}
}
return Stack.length === 0;
}
155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。void pop()删除堆栈顶部的元素。int top()获取堆栈顶部的元素。int getMin()获取堆栈中的最小元素。
思路
-
用两个栈:一个正常存数据,一个专门存最小值。
-
入栈时,新数字小于等于最小栈栈顶,就同时进最小栈,保证栈顶始终最小。
-
出栈时,如果弹出的是当前最小值,最小栈也同步弹出。
-
获取最小值直接取最小栈栈顶,不用遍历,速度最快。
//最小栈
var MinStack = function() {
this.stack = []; // 单栈:存差值
this.min = 0; // 仅一个变量存最小值
};
MinStack.prototype.push=function(val){
this.stack.push(val)
if(this.stack.length===0|| val<= this.MinStack[this.MinStack.length-1]){
this.MinStack.push(val)
}
}
MinStack.prototype.pop=function(){
let topVal= this.stack.pop(val)
if(topVal===this.MinStack[this.MinStack.length - 1]){
this.MinStack.pop()
}
}
MinStack.prototype.top = function () {
// 直接返回主栈的最后一个元素(栈顶)
return this.stack[this.stack.length - 1 ];
};
MinStack.prototype.getMin = function () {
// 最小栈的栈顶,永远是当前最小值
// 直接拿,不用遍历!!!
return this.minStack[this.minStack.length - 1]
};
394. 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入: s = "3[a]2[bc]"
输出: "aaabcbc"
典型解法:单调栈,时间复杂度 O (n)。
var decodeString = function(s) {
const stack = [];
let currentStr = '';
// 当前累计的数字(处理多位数)
let currentNum = 0;
for(let i = 0; i < s.length; i++){
const char = s[i];
if(char >= '0' && char <= '9'){
currentNum=currentNum*10+Number(char)
}
else if(char==='['){
stack.push[currentStr,currentNum]
let currentStr=''
let currentNum =0
}
else if(char===']'){
let [prevStr,num] =stack.pop()
currentStr= prevStr + currentStr.repeat(num);
}
else {
currentStr = currentStr+char
}
}
return currentStr
}
739. 每日温度
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
-
用栈保存下标,保证栈里对应的温度单调递减
-
遍历每一天:
- 如果当前温度 > 栈顶温度,说明栈顶那天找到了更暖和的一天
- 弹出栈顶,计算天数差
- 重复直到栈空或栈顶温度更大
- 把当前下标压入栈 示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
var dailyTemperatures = function(temperatures) {
const n = temperatures.length;
const res = new Array(n).fill(0);
const stack = [];
for (let i = 0; i < n; i++) {
while(stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]){
let topIndex = stack.pop(); // 弹出栈顶那天的下标
res[topIndex] = i - topIndex; // 天数差就是答案
}
stack.push(i);
}
return res;
}