1.题目来源
2.解法
1.第一种解法–Java api解法
总体的思路就是不断的删除相邻的左右括号 这种括号包括()、[]、{}三种类型 并且必须是相邻的
public boolean isValid(String s){
while(s.contains("()") || s.contains("[]") || s.contains("{}")){
s = s.replace("()", "");
s = s.replace("[]", "");
s = s.replace("{}", "");
}
return s.isEmpty();
}
但是这种解法的效率实在低下 所以使用我们今天的主角–栈进行解题
2.第二种解法–栈解法
总体的思路就是:
我们是看到这道题的实例才想到要用栈来解题的 因为从实例很明显的看出最先访问到的左字符最后和右字符进行匹配操作 这和栈的先入后出的特点很相似
我们讲讲思路:首先我们扫描所有的字符
遇到左字符的话 将其入栈
遇到右字符的话 那么如果此时栈为空的话那么说明这不是一个有效的括号
如果栈不为空的话 那么我们就匹配当前的左右字符
如果相匹配的话 那么继续匹配下一对字符
不匹配的话 直接说明这不是一个有效的括号
等到所有的字符都扫描完毕以后 如果栈为空的话 说明这才是一个有效的字符 否则就不是
1.代码实现
public boolean isValid(String s){
// 获取一下字符串的长度
int length = s.length();
// 接着创建一个栈 用于存放左字符
Stack<Character> stack = new Stack<>();
for(int i = 0; i < length; ++i){
// 获取当前扫描到的字符
char c = s.charAt(i);
if(c == '(' || c == '[' || c == '{'){
stack.push(c);
}else{
// 如果遇到的是右字符并且当前栈为空的话
if(stack.isEmpty())return false;
char left = stack.pop();
// 如果当前左右字符不匹配的话
if(left == '(' && c != ')')return false;
if(left == '[' && c != ']')return false;
if(left == '{' && c != '}')return false;
}
}
// 如果最后栈为空的话 说明这是一个有效的括号 否则就不是
return stack.isEmpty();
}
2.改进
其实我们在判断当前扫描字符是否是左字符或者左右字符是否相匹配的时候用的语句过于冗余 所以这些都有值得改进的地方
我们可以准备一个map集合 这是一个储存键值对的集合 我们可以用它来储存元素为左字符-右字符的键值对
public boolean isValid(String s){
HashMap<Character, Character> map = new HashMap<>();
map.put('(', ')');
map.put('[', ']');
map.put('{', '}');
// 获取字符串的长度
int length = s.length();
// 接着创建一个栈
Stack<Character> stack = new Stack<>();
for(int i = 0; i < length; ++i){
// 获取当前扫描到的字符
char c = s.charAt(i);
// 如果当前扫描到的是左字符的话
if(map.containsKey(c)){
stack.push(c);
}else{
// 如果遇到的是右字符的话 那么首先判断一下栈是否为空 如果为空的话 那么说明这不是一个有效的括号
if(stack.isEmpty())return false;
// 然后获取栈中的左字符
char left = stack.pop();
// 然后根据该左字符获取对应的右字符
char right = map.get(left);
// 判断左右字符是否匹配 匹配则继续看下一对字符 不匹配的话 则直接说明这不是一个有效的括号
if(right != c)return false;
}
}
// 然后判断最后栈是否为空 如果为空的话 说明这是一个有效的括号 反之则不是
return stack.isEmpty();
}