Topic description

Given a string s that only includes '(',')','{','}','[',']' ---, determine whether the string is valid.

A valid string must satisfy:

Opening parentheses must be closed with closing parentheses of the same type.
Left parentheses must be closed in the correct order.

Example 1:

 输入:s = "()"
输出:true

Example 2:

 输入:s = "()[]{}"
输出:true

Example 3:

 输入:s = "(]"
输出:false

Example 4:

 输入:s = "([)]"
输出:false

Example 5:

 输入:s = "{[]}"
输出:true
Leetcode original title address: https://leetcode.cn/problems/valid-parentheses

Thought analysis

After reading the requirements of the above topics, we can roughly understand the following points:

  • First of all, the parentheses appear in pairs. If there is a left parenthesis, there is a corresponding right parenthesis, so the length of the parenthesis string must be a multiple of 2, that is, an even number, to meet the basic conditions, namely: s.length % 2 === 0 modulo If 2 equals 1, it is an odd number, which is definitely not acceptable.
  • When a parenthesis appears, at some point in the future, another pair of parentheses will appear, paired with him. So we can also understand it in another way, which is more helpful for us to solve the problem.

    understand differently

    This analogy is inappropriate, but it helps to understand the topic

仓库(字符串)(括号) ,有大人的鞋子---002420f3b02ba23d915b6aa52bb1df36 (大括号) 、和小孩的鞋子(小括号) Right foot (左括号和右括号) . The boss asked us to pair the shoes with a left shoe and a right shoe

A condition must be added here: the left shoe can be matched to the corresponding right shoe, and vice versa. What should we ask? Because bracket matching can only be left first and then right, there is no right bracket first, then left bracket

So we 遍历 this warehouse, took out the shoes one by one. Use a pen to write down on 一张纸 the model of the other shoe that needs to be matched with the current shoe (纸张记下匹配需求) , after recording, we will put this piece of paper in an unused In the shoe box (入栈) , if we keep recording, there will be many sheets of paper in the shoe box, and even the shoe box can't fit in it (栈溢出) , so we need to compare and see what we get later Shoes, is it the shoes you need written on the paper in the shoe box (see if you can match it), 能匹配上,就把鞋盒子里这张纸,拿出来(出栈),说明匹配成功; If it doesn't match, just continue to draw a piece of paper and write on this one in your hand Shoes, what model is the other shoe you need (继续入栈) , do this until the operation is finished.

After the operation, check to see if there is any paper in the shoe box. If there is, it means that there are shoes that do not match. If there is no paper, it means everything matches

Everyone uses their imagination and imagines this scenario. If you understand this scenario, look at the code below, and you will understand it very well.

Use stack array to solve

 var isValid = function (s) {
    // 1. 如果是奇数个,肯定是不符合条件的,因为括号是成对成对出现的
    if (s.length % 2 === 1) {
        return false
    }
    // 2. 如果是偶数个,再进一步做判断,看是否符合
    let stackArr = [] // 3. 定义一个栈(数组)用来存放配对需要的标识
    for (let i = 0; i < s.length; i++) { // 4. 遍历拿到字符串中每一个括号
        // 5. 一开始栈数组是空的,所以不用对比,继续往下看
        if (stackArr[stackArr.length - 1] === s[i]) {
            stackArr.pop()
        } 
        // 6. 接下来根据遇到的是什么括号,往栈数组中入栈所需要的另一半括号
        else {
            if (s[i] === '(') { // 7. 如果是左小括号,就在栈数组中追加一个标记,需要右小括号,进行搭配
                stackArr.push(')')
            } else if (s[i] === '[') { // 8. 如果是左中括号,就在栈数组中追加一个标记,需要右中括号,进行搭配
                stackArr.push(']')
            } else if (s[i] === '{') { // 9. 如果是左大括号,就在栈数组中追加一个标记,需要右大括号,进行搭配
                stackArr.push('}')
            } else { // 10. 如果直接就直接遇到了右小括号、右中括号、右大括号,那就说明是有问题的,因为只能是左匹配右,不能右匹配左
                return false // 11. 比如咱们正常使用括号()  []  {} 从来不会这样用 )(   ][   }{
                // 12. 加之上方的if判断,是不能出现这种情况的,如果出现了,就说明括号字符串是有问题的,直接false即可
            }
        }
    }
    // 13. 匹配完了以后,看看是否有没匹配上的
    if (stackArr.length == 0) { // 14. 要是都匹配上了,说明就是没问题的,返回true
        return true
    } else { // 15. 反之,说明不符合
        return false
    }
};

Use the Map collection to simplify code

It can be understood as using the Map collection to create a requirement matching dictionary

 var isValid = function (s) {
    if (s.length % 2 === 1) {
        return false
    }
    let map = new Map() // 创建一个map集合
    map.set('(', ')') // 左小括号匹配右小括号
    map.set('[', ']') // 左中括号匹配右中括号
    map.set('{', '}') // 左大括号匹配右大括号
    let stackArr = []
    for (let i = 0; i < s.length; i++) {
        if (stackArr[stackArr.length - 1] === s[i]) {
            stackArr.pop()
        }
        else {
            if (map.has(s[i])) { // 若当下的这个半拉括号在map集合中有,即要么( 要么[ 要么{
                let need = map.get(s[i]) // 那就拿到对应所需要的另一半的值,要么) 要么] 要么}
                stackArr.push(need) // 然后把入栈告知需要的另一半括号是啥,等待匹配之
            } else { // 如果map集合中没有,说明就是遇到了) 或] 或},那就是有问题的,所以直接返回false
                return false
            }
        }
    }
    if (stackArr.length == 0) {
        return true
    } else {
        return false
    }
};

A simple understanding of stack in js

我们知道数组比较灵活,可以头部追加元素unshift头部删除元素shift尾部追加元素push尾部删除元素pop ,或者直接splice想怎么How to operate. But the stack doesn't work.

Imagine, 数组平常是横着的,而栈就是竖着的,立起来的 . Therefore, there is only one entry above, and adding or deleting elements can only be performed through the entry above.

A stack is a restricted array, also known as a stack array

That is to say, the stack array can only be push尾部追加 and pop尾部删除 , that is, the elements added first can only be deleted later; the elements added later can be deleted first. That is: 先进后出,或后进先出

As for the queue, it is actually a restricted array, which can also be called a queue array. For reasons of space, I will not go into details here.

Finally, a point of view is thrown. When we do algorithm problems, we do not necessarily have to be exactly the same as the official solutions of leetcode. As long as the thinking is the same, after all, everything changes, thinking is very important ^_^


水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负