难度:简单
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
提示:
1 <= s.length <= 10^4
s
仅由括号 '()[]{}'
组成思路:
class Solution {
private static final Map<Character, Character> charMap;
static {
charMap = new HashMap<>(4);
charMap.put('(', ')');
charMap.put('{', '}');
charMap.put('[', ']');
}
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
if (charMap.containsKey(s.charAt(i))) {
stack.push(charMap.get(s.charAt(i)));
} else if (stack.isEmpty() || s.charAt(i) != stack.pop()) {
return false;
}
}
return stack.isEmpty();
}
}
算法原理
栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack
仍然为空;
建立哈希表 dic
构建左右括号对应关系:key
左括号,value
右括号;这样查询 2
个括号是否对应只需 O(1) 时间复杂度;建立栈 stack
,遍历字符串 s
并按照算法流程一一判断。
算法流程
提前返回false
提前返回优点: 在迭代过程中,提前发现不符合的括号并且返回,提升算法效率。
解决边界问题:
栈 stack 为空: 此时 stack.pop() 操作会报错;因此,我们采用一个取巧方法,给 stack 赋初值 ?
,并在哈希表 dic 中建立对应关系予以配合。此时当 stack 为空且 c 为右括号时,可以正常提前返回 false;
字符串 s 以左括号结尾: 此情况下可以正常遍历完整个 s,但 stack 中遗留未出栈的左括号;因此,最后需返回 len(stack) == 1,以判断是否是有效的括号组合
复杂度分析
class Solution {
private static final Map<Character,Character> map = new HashMap<Character,Character>(){{
put('{','}'); put('[',']'); put('(',')'); put('?','?');
}};
public boolean isValid(String s) {
if(s.length() > 0 && !map.containsKey(s.charAt(0))) return false;
LinkedList<Character> stack = new LinkedList<Character>() {{ add('?'); }};
for(Character c : s.toCharArray()){
if(map.containsKey(c)) stack.addLast(c);
else if(map.get(stack.removeLast()) != c) return false;
}
return stack.size() == 1;
}
}
作者:Krahets
链接:https://leetcode.cn/problems/valid-parentheses/solutions/9185/valid-parentheses-fu-zhu-zhan-fa-by-jin407891080/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。