这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战
leetcode 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
解题: 可以利用栈先进后出的特性来比较一对括号是否有效(相同类型的左括号匹配相同类型的右括号),类似于(){}[]、({[]}),对于一个左括号期望其后一个右括号是与其类型对应的。那么可以遍历字符串遇到左括号字符,将这个左括号入栈,直到遇到右括号,就出栈一个左括号,判断是否匹配,不匹配就不合法了,否则继续。首先有效括号都是成对的,所以可以先判断括号个数不是偶数个的,最终肯定是无效的了,然后就可以遍历字符串,凡是遇到左括号都统一入栈,遇到右括号就取出最后一个左括号判断是不是匹配。遍历过程中遇到的最后一个左括号和最先遇到的右括号肯定得是匹配的,同样下一个右括号肯定和上一个左括号匹配才行,所以用栈可以比较方便的来判断,但是有可能遇到右括号的时候,出栈前发现栈里没有元素,说明前面已经没有左括号可以和它匹配了,那么整个字符串就不是有效的了。
class Solution {
public boolean isValid(String s) {
int len = s.length();
// 括号个数不是偶数个的 那么肯定不是对的
if (len % 2 != 0) {
return false;
}
char c;
// 利用栈先进后出的特点来做判断
Deque<Character> stack = new LinkedList<Character>();
for (int i = 0; i < len; i++) {
c = s.charAt(i);
// 如果是左括号就统一先入栈
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
continue;
}// 空栈说明前面没有左括号了,这个时候的右括号匹配个寂寞
if (stack.isEmpty()) {
return false;
}
// 如果是右括号就出栈一个左括号来比较和当前右括号是不是一对
// 当前括号是)但是出栈的不是(
if (c == ')' && stack.pop() != '(') {
return false;
}// 当前括号是}但是出栈的不是{
if (c == ']' && stack.pop() != '[') {
return false;
}// 当前括号是]但是出栈的不是[
if (c == '}' && stack.pop() != '{') {
return false;
}
}
return stack.isEmpty();
}
}
或者:
class Solution {
public static Map<Character, Character> brackets;
static {
brackets = new HashMap<Character, Character>();
brackets.put(')', '(');
brackets.put('}', '{');
brackets.put(']', '[');
}
public boolean isValid(String s) {
int len = s.length();
// 括号个数不是偶数个的 那么肯定不是对的
if (len % 2 != 0) {
return false;
}
char c;
Deque<Character> stack = new LinkedList<Character>();
for (int i = 0; i < len; i++) {
c = s.charAt(i);
// 左括号入栈
if (brackets.containsValue(c)) {
stack.push(c);
continue;
}
// 右括号
// 空栈 或者出栈元素不匹配
if (stack.isEmpty() || !stack.pop().equals(brackets.get(c))) {
return false;
}
}
return stack.isEmpty();
}
}