题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
我的题解
分析:
这种匹配性问题,我的一个想法是利用栈:遍历字符数组,如果当前字符和栈顶匹配,就弹出栈顶,转到下一个字符;如果不匹配,就加入栈。最后如果栈为空,就是合法的,否则不合法!
1 class Solution { 2 Stack<Character> stack = new Stack<>(); 3 public boolean isValid(String s) { 4 5 char [] strArr = s.toCharArray(); 6 7 for (char c: strArr){ 8 //如果栈顶char和当前char相同,匹配,弹出栈顶,处理下一个 9 if (match(c)) stack.pop(); 10 else stack.push(c); 11 } 12 if (stack.empty()) return true; 13 return false; 14 } 15 16 private boolean match(char c){ 17 if (stack.empty())return false; 18 int tmp = c-stack.peek(); 19 if (tmp==1||tmp==2)return true;//'('与')'的ASCII值差1,'['与']','{'与'}'的ASCII值差2 20 return false; 21 } 22 }
执行用时 :2 ms, 在所有 Java 提交中击败了92.12%的用户
内存消耗 :38.1 MB, 在所有 Java 提交中击败了5.01%的用户
忽略了一个重要的点:如果字符串是奇数位数,不可能匹配,直接返回false
if(strArr.length%2==1) return false;
加了这个判断:
执行用时 :1 ms, 在所有 Java 提交中击败了98.97%的用户
这种方法效率还不错,但是使用了栈就带来了空间复杂度。
其他题解
1 class Solution: 2 def isValid(self, s): 3 while '{}' in s or '()' in s or '[]' in s: 4 s = s.replace('{}', '') 5 s = s.replace('[]', '') 6 s = s.replace('()', '') 7 return s == ''
该解法思维奇特:我们知道如果字符串合法,那么里面一定至少存在一个匹配,{}或()或[],去掉该匹配,又会至少存在一个匹配,如果循环,就会去掉了所有的匹配项,最后如果是空串就表示合法。
但是效率低下:每次至少需要一次子串的查找,找到后还需要替换,时间复杂度很高。
另外还有一个解法不错,利用字典:
{")": "(", "]":"[", "}": "{"}