✅✅代码随想录算法训练营Day11|| 232.用栈实现队列 ,225. 用队列实现栈 ,20. 有效的括号,1047. 删除字符串中的所有相

124 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情🚀🚀

前言

从今天开始,在算法这边花的时间要比之前少一两个小时了,技术栈那边需要我去兼顾了。。

国庆也不能停下来呀~

232. 用栈实现队列 - 力扣(LeetCode)

难度:🔥🔥🔥

image.png

用两个栈实现队列

var MyQueue = function() {
   this.stackIn = [];
   this.stackOut = [];
};


MyQueue.prototype.push = function(x) {
   this.stackIn.push(x);
};


MyQueue.prototype.pop = function() {
   const size = this.stackOut.length;
   if(size) {
       return this.stackOut.pop();
   }
   while(this.stackIn.length) {
       this.stackOut.push(this.stackIn.pop());
   }
   return this.stackOut.pop();
};


MyQueue.prototype.peek = function() {
   const x = this.pop();
   this.stackOut.push(x);
   return x;
};


MyQueue.prototype.empty = function() {
   return !this.stackIn.length && !this.stackOut.length
};

难点

两个栈

push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。

MyQueue.prototype.push = function(x) {
   this.stackIn.push(x);
};


MyQueue.prototype.pop = function() {
   const size = this.stackOut.length;
   if(size) {
       return this.stackOut.pop();
   }
   while(this.stackIn.length) {
       this.stackOut.push(this.stackIn.pop());
   }
   return this.stackOut.pop();
};

this

经常会忘记用this指向MyQueue构造函数创建出的实例对象。

225. 用队列实现栈 - 力扣(LeetCode)

难度:🔥🔥

image.png

用一个队列实现栈

var MyStack = function() {
    this.queue = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function(x) {
    this.queue.push(x);
};

/**
 * @return {number}
 */
MyStack.prototype.pop = function() {
    let size = this.queue.length;
    while(size-- > 1){
        this.queue.push(this.queue.shift());
    }
    return this.queue.shift();
};

/**
 * @return {number}
 */
MyStack.prototype.top = function() {
    const x = this.pop();
    this.queue.push(x);
    return x
};

/**
 * @return {boolean}
 */
MyStack.prototype.empty = function() {
    return this.queue.length == 0
};

难点

一个队列实现

为什么说可以只用一个队列实现呢?

因为在实现pop()方法时,可以将队尾前面的所有元素移除,然后再接到队尾元素后面,这样就OK了~

MyStack.prototype.pop = function() {
    let size = this.queue.length;
    while(size-- > 1){
        this.queue.push(this.queue.shift());
    }
    return this.queue.shift();
};

unshift和shift

这两个方法经常容易混淆~😡 😡

  • unshift:在数组的头部加入一个元素
     var arr = [1,2,3];
     console.log(arr.unshift(4));//4
     console.log(arr);//[4,1,2,3]
    
  • shift:删除数组头部的第一个元素,并返回这个元素。
    var arr = [1,2,3];
    console.log(arr.shift());//1 
    console.log(arr);//[2,3]
    

20. 有效的括号 - 力扣(LeetCode)

难度:🔥🔥🔥

image.png

用栈去匹配

var isValid = function(s) {
    let stack = [];
    for(const i of s){
        switch(i){
            case'(':
            stack.push(')');
            break;
            case'[':
            stack.push(']');
            break;
            case'{':
            stack.push('}');
            break;
            default:
                if( i != stack.pop() )
                return false;
        }
    }
    if(stack.length){
        return false;
    }
    return true
};

chrome-capture-2022-9-2.gif

难点

分清楚情况

说来说去,就是两种情况,一个是类型不匹配,一个就是数量不匹配。

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

难度:🔥🔥

image.png

用栈去匹配 => 消消乐

var removeDuplicates = function(s) {
    let stack = [];
    for(let i of s){
        if(stack[stack.length-1] != i){
            stack.push(i);
        }
        else{
            stack.pop(i);
        }
    }
    return stack.join('')
};

本题也是用栈来解决的经典题目。

那么栈里应该放的是什么元素呢?

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

然后再去做对应的消除操作。 如动画所示:

chrome-capture-2022-9-2.gif

参考文章

代码随想录 (programmercarl.com)