代码随想录的第十天

67 阅读1分钟

代码随想录的第十天

20. 有效的括号

栈思想:

var isValid = function(s) {
    const stack = []
    for (let i = 0;i < s.length; i++) {
        if (s[i] === '(' || s[i] === '{' || s[i] === '[') {
            stack.push(s[i])
        } else {
            const p = stack[stack.length - 1]
            if (
                (s[i] === ')' && p === '(') ||
                (s[i] === ']' && p === '[') ||
                (s[i] === '}' && p === '{')
            ) {
                stack.pop()
            } else {
                return false
            }
        }
    }
    return stack.length ? false : true
};
var isValid = function(s) {
    const map = new Map()
    const stack = []
    map.set('(',')')
    map.set('[',']')
    map.set('{','}')
    for (let i = 0; i< s.length; i++) {
        const c= s[i]
        if (map.has(c)) {
            stack.push(c)
        } else {
            const p = stack[stack.length - 1]
            if (map.get(p) === s[i]) {
                stack.pop()
            } else {
                return false
            }
        }
    }
    return stack.length ? false : true
};

思路:

1、利用栈后入先出的思想,因为如果是有效的括号那么肯定是对称的

2、栈在右括号刚入栈的时候,肯定和上一个左括号是闭合的,利用这个思路将数组一对一对进行抛出

3、最后为空即为有效括号

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

栈思想:

var removeDuplicates = function(s) {
    const stack = []
    for (let i = 0; i < s.length; i++) {
        if (i > 0 && stack[stack.length - 1] === s[i]) {
            stack.pop()
        } else {
            stack.push(s[i])
        }
    }
    return stack.join('')
};

思路:

1、定义一个栈,从第二个字符开始,栈里面的末尾元素和新入栈的元素相同,则删除栈内元素,否则推入栈中

双指针原地删除:

var removeDuplicates = function(s) {
    s = [...s]
    let top = -1
    for (let i = 0; i < s.length; i++) {
        if (top === -1 || s[top] !== s[i]) {
            top++
            s[top] = s[i]
        } else {
            top--
        }
    }
    s.length = top + 1
    return s.join('')
};

思路:

1、在原先的s栈上模拟一个异步的栈

2、晚于s的遍历一步易于去观察是否和当前的定义的栈的元素相同,以此来判断是否是相邻的两个值

3、最后得到新栈的长度,然后截取新栈的长度得出

150. 逆波兰表达式求值

var evalRPN = function(tokens) {
    const stack = []
    for (let i = 0; i < tokens.length; i++) {
        if (tokens[i] === '+' || tokens[i] === '-' || tokens[i] === '*' || tokens[i] === '/') {
            console.log(stack)
            const nums1 = stack.pop()
            const nums2 = stack.pop()
            if (tokens[i] === '+') stack.push(nums1 + nums2)
            if (tokens[i] === '-') stack.push(nums2 - nums1)
            if (tokens[i] === '*') stack.push(nums1 * nums2)
            if (tokens[i] === '/') stack.push(nums2 / nums1 | 0)
        } else {
            stack.push(Number(tokens[i]))
        }
    }
    return stack[0]
};

思路:

1、逆波兰表达式其实就是将表达式在匹配二叉树后的后续遍历后的顺序数组

2、原理就是:如果不是符号就推入栈中,如果是符号,就将栈中的栈顶两个元素取出进行处理然后再次推进栈中,最后的栈中的元素就是所要求的值

3、需要注意的是:在进行减法和除法的时候是后一位操作前一位,并且向下取整