栈(stack)的应用之括号匹配
栈是一种后进先出的数据结构,Last In First Out(LIFO),在计算机的应用极广。
栈的应用
- undo操作(撤销)
- 程序调用的系统栈
- 括号匹配
题目:
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被认为是有效字符串。
- 有效字符串如 :
“”, “()”, “[((()))]”, " {[()()]}" - 无效字符串如:
“(]”, “])”, “[(()]”, “[])”
分析:
-
通过上述的字符串例子可以发现,右括号必须先匹配最近的左括号,且是相同类型。
-
这和栈先操作栈顶元素类似,我们可以遍历字符串,对每个字符做判断,是左括号就入栈,是右括号就将栈顶元素弹出并判断是否匹配,如果匹配不上直接返回false。
实现注意点:
- 先测试空字符串
- 右括号匹配时,对栈顶元素弹出时,要考虑栈中是否有元素,否则会抛出异常
实现:
public class Solution {
public boolean isValid(String s){
// char[] chs = s.toCharArray();//遍历一个字符串,不需要转换成字符数组。s.charAt()
Stack<Character> stack=new Stack<>();
HashMap<Character,Character> mapping=new HashMap<>();
mapping.put('}','{');
mapping.put(']','[');
mapping.put(')','(');
// 字符串长度为奇数,肯定是无效字符串,无需再进行判断,直接返回false
if(s.length()%2==1)
return false;
// 遍历字符串
for(int i=0;i<s.length();i++){
// char[] chs = s.toCharArray();遍历一个字符串,不需要转换成字符数组。s.charAt()
char ch=s.charAt(i);
if(mapping.containsKey(ch)){
// 若栈为空,调用peek、pop方法,会抛出异常。
// 解决方法1:可以使用捕捉异常返回false;
// 解决方法2:但最好进行判断是否为空,为空返回一个虚拟值(dummy value),这样就可以和右括号与栈顶左括号不匹配的情况写在一个逻辑中
char temp=stack.isEmpty()?'#':stack.pop();
if(mapping.get(ch)!=temp){
return false;
}
}
// 若为左括号,则将元素推入栈中
if(mapping.containsValue(ch)){
stack.push(ch);
}
}
// 遍历之后栈中仍有元素返回false
return stack.isEmpty();
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses