20. 有效的括号
题目
原题链接:https://leetcode-cn.com/problems/valid-parentheses/
给定一个只包括'('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例:
输入: "()"
输出: true
输入: "()[]{}"
输出: true
输入: "(]"
输出: false
输入: "([)]"
输出: false
输入: "{[]}"
输出: true
解题思路
使用栈:
- 有效括号字符串的长度,一定是偶数!
- 右括号前面,必须是相对应的左括号,才能抵消!右括号前面,不是对应的左括号,那么该字符串,一定不是有效的括号!因此,如果遇到左括号,则压入栈;如果遇到右括号,两者对应(右括号前面,必须是相对应的左括号),则抵消,弹出栈顶。!
代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
/**
* 20.有效的括号
* @date 2021/5/17
* @author chenzufeng
*/
public class No20_ValidParentheses {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
System.out.println(isValid(str));
}
public static boolean isValid(String str) {
int length = str.length();
// 有效括号字符串的长度,一定是偶数
if (length % 2 == 1) {
return false;
}
// 为了快速判断括号类型,使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号
Map<Character, Character> hashMap = new HashMap<Character, Character>(3) { {
put(')', '('); put(']', '['); put('}', '{');
}
};
// 使用栈来遍历
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < length; i++) {
// 某个括号
char ch = str.charAt(i);
// 如果遇到右括号,两者对应(右括号前面,必须是相对应的左括号),则抵消,弹出栈顶
if (hashMap.containsKey(ch)) {
// 右括号前面,必须有相对应的左括号,如果栈中没有与此右括号匹配的左括号,则返回false
if (stack.isEmpty() || ! stack.peek().equals(hashMap.get(ch))) {
return false;
}
// 满足条件,则出栈
stack.pop();
} else {
// 如果遇到左括号,则压入栈
stack.push(ch);
}
}
// 最后如果栈不为空,则返回false
return stack.isEmpty();
}
}
复杂度分析
时间复杂度:\(O(n)\),其中\(n\)是字符串\(s\)的长度。
空间复杂度:\(O(n + |\Sigma|)\),其中\(\Sigma\)表示字符集,本题中字符串只包含\(6\)种括号,\(|\Sigma| = 6\)。栈中的字符数量为\(O(n)\),而哈希表使用的空间为\(O(|\Sigma|)\),相加即可得到总空间复杂度。