Day10: 栈与队列基础 |

232.用栈实现队列

class MyQueue {
    stack: number[];
    stack2: number[];
    constructor() {
        this.stack = new Array();
        this.stack2 = new Array();
    }

    push(x: number): void {
        this.stack.push(x);
    }

    pop(): number {
        while(this.stack.length){
            this.stack2.push(this.stack.pop())
        }
        let removedVal = this.stack2.pop();
        while(this.stack2.length){
            this.stack.push(this.stack2.pop())
        }
        return removedVal;
    }

    peek(): number {
        while(this.stack.length){
            this.stack2.push(this.stack.pop())
        }
        let peekVal = this.stack2.pop();
        this.stack2.push(peekVal);
        while(this.stack2.length){
            this.stack.push(this.stack2.pop())
        }
        return peekVal;
    }

    empty(): boolean {
        return this.stack.length === 0;
    }
}

官方题解:

这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。

使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。

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

最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。

class MyQueue {
    private stackIn: number[]
    private stackOut: number[]
    constructor() {
        this.stackIn = [];
        this.stackOut = [];
    }

    push(x: number): void {
        this.stackIn.push(x);
    }

    pop(): number {
        if (this.stackOut.length === 0) {
            while (this.stackIn.length > 0) {
                this.stackOut.push(this.stackIn.pop()!);
            }
        }
        return this.stackOut.pop()!;
    }

    peek(): number {
        let temp: number = this.pop();
        this.stackOut.push(temp);
        return temp;
    }

    empty(): boolean {
        return this.stackIn.length === 0 && this.stackOut.length === 0;
    }
}

225. 用队列实现栈

class MyStack {
    private queue1: number[];
    private queue2: number[];
    constructor() {
        this.queue1 = [];
        this.queue2 = [];
    }

    push(x: number): void {
        if (this.queue1.length > 0) {
            this.queue1.push(x);
        } else {
            this.queue2.push(x);
        }
    }

    pop(): number {
        if (this.queue1.length > 0) {
            while (this.queue1.length > 0) {
                if (this.queue1.length === 1) {
                    let top = this.queue1.shift();
                    return top;
                }
                this.queue2.push(this.queue1.shift());
            }
        } else if (this.queue2.length > 0) {
            while (this.queue2.length > 0) {
                if (this.queue2.length === 1) {
                    let top = this.queue2.shift();
                    return top;
                }
                this.queue1.push(this.queue2.shift());
            }
        }
    }

    top(): number {
        if (this.queue1.length > 0) {
            while (this.queue1.length > 0) {
                if (this.queue1.length === 1) {
                    let top = this.queue1.shift();
                    this.queue2.push(top);
                    return top;
                }
                this.queue2.push(this.queue1.shift());
            }
        } else if (this.queue2.length > 0) {
            while (this.queue2.length > 0) {
                if (this.queue2.length === 1) {
                    let top = this.queue2.shift();
                    this.queue1.push(top);
                    return top;
                }
                this.queue1.push(this.queue2.shift());
            }
        }
    }

    empty(): boolean {
        return this.queue1.length === 0 && this.queue2.length === 0;
    }
}

/**
 * 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()
 */

官方题解:

版本一: 用两个队列模拟栈,由于官方题解始终只保持一个题解有值,所以

class MyStack {
    private queue: number[];
    private tempQueue: number[];
    constructor() {
        this.queue = [];
        this.tempQueue = [];
    }

    push(x: number): void {
        this.queue.push(x);
    }

    pop(): number {
        for (let i = 0, length = this.queue.length - 1; i < length; i++) {
            this.tempQueue.push(this.queue.shift()!);
        }
        let res: number = this.queue.pop()!;
        let temp: number[] = this.queue;
        this.queue = this.tempQueue;
        this.tempQueue = temp;
        return res;
    }

    top(): number {
        let res: number = this.pop();
        this.push(res);
        return res;
    }

    empty(): boolean {
        return this.queue.length === 0;
    }
}

优化:其实这道题目就是用一个队列就够了。

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。

class MyStack {
    private queue: number[];
    constructor() {
        this.queue = [];
    }

    push(x: number): void {
        this.queue.push(x);
    }

    pop(): number {
        for (let i = 0, length = this.queue.length - 1; i < length; i++) {
            this.queue.push(this.queue.shift()!);
        }
        return this.queue.shift()!;
    }

    top(): number {
        let res: number = this.pop();
        this.push(res);
        return res;
    }

    empty(): boolean {
        return this.queue.length === 0;
    }
}

20. 有效的括号

function isValid(s: string): boolean {
    let leftBrackets = [];
    let brackets = [...s];
    for(let bracket of brackets){
        if(['(', '[', '{'].includes(bracket)){
            leftBrackets.push(bracket);
        } else{
            let leftBracket = leftBrackets.pop();
            switch(bracket){
                case ')': if(leftBracket !== '(') return false; break;
                case '}': if(leftBracket !== '{') return false; break;
                case ']': if(leftBracket !== '[') return false; break;
            }
        }
    }
    if(leftBrackets.length > 0) return false;
    return true;
};

如果 switch 后面有公共逻辑,可以不用 break; 把公共逻辑抽象出来,写到 default 里面去,类似官方题解普通版解法:

function isValid(s: string): boolean {
    let helperStack: string[] = [];
    for (let i = 0, length = s.length; i < length; i++) {
        let x: string = s[i];
        switch (x) {
            case '(':
                helperStack.push(')');
                break;
            case '[':
                helperStack.push(']');
                break;
            case '{':
                helperStack.push('}');
                break;
            default:
                if (helperStack.pop() !== x) return false;
                break;
        }
    }
    return helperStack.length === 0;
};

官方题解优化版本:

function isValid(s: string): boolean {
    type BracketMap = {
        [index: string]: string;
    }
    let helperStack: string[] = [];
    let bracketMap: BracketMap = {
        '(': ')',
        '[': ']',
        '{': '}'
    }
    for (let i of s) {
        if (bracketMap.hasOwnProperty(i)) {、
            // 左括号
            helperStack.push(bracketMap[i]);
        } else if (i !== helperStack.pop()) {
            // 右括号
            return false;
        }
    }
    return helperStack.length === 0;
};

hasOwnProperty() 方法返回一个布尔值,表示对象自有属性(而不是继承来的属性)中是否具有指定的属性。

1047. 删除字符串中的所有相邻重复项

function removeDuplicates(s: string): string {
    let helperStact = [];
    for(let letter of s){
        let lastLetterInStack = helperStact.pop();
        if(!lastLetterInStack) {
            helperStact.push(letter);
            continue;
        }
        if(lastLetterInStack === letter) continue;
        helperStact.push(lastLetterInStack);
        helperStact.push(letter);
    }
    return helperStact.join('');
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值