Loading

有效的括号

1.问题描述

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。

  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

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

示例 3:

输入: "(]"
输出: false

示例 4:

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

示例 5:

输入: "{[]}"
输出: true

2.求解

  1. 遍历字符串s,当我们遇到一个左括号时,我们期望在后面的遍历中出现右括号将其闭合。因为括号的特性是:后遇到的括号先闭合,于是我们可以使用这一数据结构来解决
  2. 遍历到一个左括号时,我们将其压入栈中,遇到右括号时,出现了闭合需求,我们检查栈顶是否为对应的左括号,若不是则直接返回flase,若是则继续遍历
  3. 那么应该如何指示括号的对应关系,此时我们想到了哈希表,把左向括号用作key,将右向括号用作value放入哈希表中
  4. 因为字符串中只会出现括号,那么我们具体的逻辑就是,遍历到一个字符,先检查是否是右向括号,若不是,则压入栈中
  5. 若是右向括号,则检查当前栈顶是否为对应左括号,若是,则弹出当前栈顶,若不是,则说明字符串无效,返回false
  6. 在拿到字符串的时候还可以进行一次剪枝操作,若字符串长度是奇数,则说明字符串无效,直接返回false
代码如下
/*
执行用时:2 ms, 在所有 Java 提交中击败了77.77%的用户
内存消耗:37.3 MB, 在所有 Java 提交中击败了8.87%的用户
*/
public boolean isValid(String s) {
    if(s.length() % 2 != 0){
        return false;
    }

    Map<Character,Character> pairs = new HashMap<>();
    pairs.put(')','(');
    pairs.put('}','{');
    pairs.put(']','[');

    Deque stack = new LinkedList();
    char[] chars = s.toCharArray();
    for(int i = 0; i < chars.length; i++){
        char ch = chars[i];
        if(pairs.containsKey(ch)){
            if(stack.peek() != pairs.get(ch)){
                return false;
            }else{
                stack.pop();
            }
        }else {
            stack.push(ch);
        }
    }
    return stack.isEmpty();
}
  • 时间复杂度O(n),只有对字符串的一次遍历
  • 空间复杂度O(n+6),字符串存储占用n的空间,哈希表占用6个字符

ArrayList和LinkList区别

LinkList用作栈和队列

不使用哈希结构

查询ASCII码表发现两括号之间的ASCII差值是1或者2,又因为字符串中指挥出现左右向括号,所以我们可以利用括号之间的差值来检查括号是否匹配。

ASCII查询

代码如下
/*
执行用时:1 ms, 在所有 Java 提交中击败了98.78% 的用户

内存消耗:36.7 MB, 在所有 Java 提交中击败了83.92% 的用户
*/
public boolean isValid(String s) {
    if(s.length() % 2 != 0){
        return false;
    }
    if (s.isEmpty()){
        return true;
    }
    Deque<Character> stack = new LinkedList();
    char[] chars = s.toCharArray();
    for(char ch : chars){
        if (ch == '(' || ch == '[' || ch == '{') {
            stack.push(ch);
        } else if (stack.isEmpty() || Math.abs(ch - stack.pop()) > 2) {
            return false;
        }
    }
    return stack.isEmpty();
}

消消乐解法

代码如下
/*
执行用时:54 ms, 在所有 Java 提交中击败了5.00% 的用户

内存消耗:39.3 MB, 在所有 Java 提交中击败了5.02% 的用户
*/
public boolean isValid(String s) {
    while (s.contains("()") || s.contains("[]") || s.contains("{}")) {
        if (s.contains("()")) {
            s = s.replace("()", "");
        }
        if (s.contains("{}")) {
            s = s.replace("{}", "");
        }
        if (s.contains("[]")) {
            s = s.replace("[]", "");
        }
    }
    return s.length() == 0;
}
posted @ 2020-10-07 10:32  水纸杯  阅读(130)  评论(0)    收藏  举报