(算法)栈与队列(上)

47 阅读2分钟

有效括号

给定一个只包括 '(',')','{','}','[',']'的字符串,判断字符串是否有效。

有效字符串需满足: 左括号必须用相同类型的右括号闭合,左括号必须以正确的顺序闭合。
注意:空字符串可被认为是有效字符串。

示例:

示例 1:
输入: "()"
输出: true

示例 2:  
输入: "()[]{}"  
输出: true

示例 3:
输入: "(]"
输出: false

示例 4:
输入: "([)]"
输出: false

示例 5:
输入: "{[]}"
输出: true

题解:

/** 
* @param {string} str
* @return {boolean} 
*/
const isValid = (str) => {
    //存储相应匹配
   const leftToRightMap = new Map();
   leftToRightMap.set('{', '}');
   leftToRightMap.set('(', ')');
   leftToRightMap.set('[', ']');
   
   if(!str) return true;
   
   const stack = [];
   for(let i = 0; i < str.length; i++){
       let match = leftTORightMap.get(str[i]);
       //获取到则入栈
       if(match) {
           stack.push(match);
           continue; //跳出本次
       }
       //栈为空但还有字符-> false 或者 栈顶不相等-> false
       if(!stack.length || stack.pop() !== str[i]){
           return false;
       }
   }
   //匹配完栈应为空
   return !stack.length
}

规则:

对称性、涉及括号问题,则很有可能和栈相关。

每日温度

根据每日气温列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。

示例:

输入:temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
输出:[1, 1, 4, 2, 1, 1, 0, 0]。

题解:

/** 
* @param {number[]} Arr
* @return {number[]} 
*/
const dailyTemperatures = (Arr) => {
   const len = Arr.length
   const res = (new Array(len)).fill(0);
   
   const stack = [];
   for(let i = 0; i < len; i++){
       //当数值比栈顶最小值 大 时出栈,根据存储的索引值求出相距天数
       while(stack.length && Arr[i] > Arr[stack[stack.length - 1]]){
           const top = stack.pop();
           res[top] = i - top;
       }
       //入栈索引
       stack.push(i);
   }
   
   return res
}

规则:

栈结构可以避免重复操作,及时地将不必要的数据出栈。维持一个递减栈。

最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

示例:

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.

题解 1:

/** 
* 初始化栈结构
*/
const MinStack = function(){
    this.stack = []
}

/** 
* @param {number} x 
* @return {void} 
*/
MinStack.prototype.push = function(x){
    this.stack.push(x)
}

/** 
* @return {void} 
*/
MinStack.prototype.pop = function(){
    this.stack.pop()
}

/** 
* @return {number} 
*/
MinStack.prototype.top = function(){
    if(!this.stack.length) return;
    return this.stack[this.stack.length - 1]
}

/** 
* @return {number} 
*/
MinStack.prototype.getMin = function(){
    let minVal = Infinity;
    const { stack } = this;
    for(let i = 0; i < stack.length; i++){
        if(stack[i] < minVal) minVal = stack[i];
    }
    return minVal;
}

题解 2:

/** 
* 初始化栈结构
*/
const MinStack = function(){
    this.stack = [];
    this.minValStack = [];
}

/** 
* @param {number} x 
* @return {void} 
*/
MinStack.prototype.push = function(x){
    this.stack.push(x);
    const len = this.minValStack.length;
    if(!len || x <= this.minValStack[len - 1]){
        this.minValStack.push(x);
    }
}

/** 
* @return {void} 
*/
MinStack.prototype.pop = function(){
    const x = this.stack.pop();
    if(x === this.minValStack[this.MinValStack.length - 1]){
        this.minValStack.pop();
    }
}

/** 
* @return {number} 
*/
MinStack.prototype.top = function(){
    if(!this.stack.length) return;
    return this.stack[this.stack.length - 1]
}

/** 
* @return {number} 
*/
MinStack.prototype.getMin = function(){
    return this.minValStack[this.MinValStack.length - 1];
}

规则:

栈底到栈顶呈递减趋势的栈, 栈顶为最小值