算法通关村—括号匹配问题解析

1. 有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = “()”
输出:true

20. 有效的括号

1.1 HashMap+栈

将左括号作为key,右括号作为value,然后存入map集合里面去,只有当当前字符是左括号时候,才会让其进入,否则就是右括号,然后将当前栈顶元素弹出,找到对应的右括号,然后比对两个括号是否一致。

 public static boolean isValid(String s) {
    
    
        if (s.length() <= 1) return false;
        // 将左括号作为key,右括号作为value
        HashMap<Character, Character> map = new HashMap<>();
        map.put('{', '}');
        map.put('[', ']');
        map.put('(', ')');
        // 栈记录左括号
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
    
    
            char currChar = s.charAt(i);
            // 左括号
            if (map.containsKey(currChar)) {
    
    
                // 左括号入栈
                stack.push(currChar);
            } else {
    
    
                // 右括号
                if (!stack.isEmpty()) {
    
    
                    // 栈顶元素对应左括号
                    Character leftCharKey = stack.pop();
                    // 找到对应右括号
                    Character rightChar = map.get(leftCharKey);
                    // 右括号不等于当前括号
                    if (rightChar != currChar) {
    
    
                        return false;
                    }
                    // 栈为空,表示没左括号进入
                } else {
    
    
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }

在这里插入图片描述
时间复杂度:O(n) 将字符串遍历找到左括号存入,而map的查找元素时间复杂度是O(1)

空间复杂度:map的空间复杂度是O(1),栈出去元素时间复杂度O(n/2),因为只是存入了左括号。

1.2 栈优化

可以看出,第一种方法主要是使用map来进行查找存储括号,但是由于题目已知相应的括号,那么可以稍微简化一下,我只需要判断当前字符是不是左括号,是左括号,然后将对应的右括号添加栈,如果是右括号,就比对当前括号是不是一致。

 public boolean isValid(String s) {
    
    
      Stack<Character> stack = new Stack<>();
      for(int i=0;i<s.length();i++){
    
    
          char currChar = s.charAt(i);
          if(currChar == '['){
    
    
              stack.push(']');
          }else if(currChar == '{'){
    
    
              stack.push('}');
          }else if(currChar == '('){
    
    
              stack.push(')');
          }else{
    
    
              // 右括号
              if(stack.isEmpty() || stack.pop() != currChar){
    
    
                  return  false;
              }
          }
      }
      return stack.isEmpty();
    }

在这里插入图片描述
不过这个方法只适用于少量数据括号,数据量多了,还是要使用map存储。

2. 最长有效括号

32. 最长有效括号

给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

输入:s = “(()”
输出:2
解释:最长有效括号子串是 “()”

2.1 栈

  1. 如果出现’(',保留当前下标
  2. 出现’)',先弹出栈顶元素,默认这两个括号是一对,此时长度就是右括号的下标减去左括号的下标
  3. 判断是否栈为空,为空就要把当前右括号重新放入栈里面,原因是没有找到匹配的左括号
public int longestValidParentheses(String s) {
    
    
        Stack<Integer> stack = new Stack<>();
        int maxLen =0;
        stack.push(-1);
        for(int i= 0;i<s.length();i++){
    
    
            char currChar = s.charAt(i);
            if(currChar == '(' ){
    
    
                stack.push(i);
            }else {
    
    
                stack.pop();
                if(stack.isEmpty() ){
    
    
                   stack.push(i);
                }else{
    
    
                    maxLen = Math.max(maxLen,i-stack.peek());
                }
            }
        }
        return maxLen;
    }

在这里插入图片描述

时间复杂度:O(n)
空间复杂度:O(n)

总结:这一题使用栈代码看起来简单,但是实际做的时候发现,比较难以考虑到一些边界值以及将下标放入栈里面去。

3. 类似题目

Leetcode20 有效的括号、LeetCode22 .括号生成、LeetCode32.最长有效括号、LeetCode301.删除无效的括号和leetcode 856 括号的分数等。

后面几题都涉及到了动态规划等等,之后再做。

猜你喜欢

转载自blog.csdn.net/qq_52843958/article/details/131996499