1.题目
https://leetcode.cn/problems/valid-parentheses/
2.解法
2.1 解法一:利用栈
思路
是使用一个栈来存储左括号,然后遍历字符串中的每个字符,
- 如果是左括号就入栈,
- 如果是右括号就出栈并和栈顶元素比较是否匹配。
- 如果不匹配或者栈为空,就说明字符串不是有效的括号。
最后遍历完字符串后,还要检查栈是否为空,如果不为空,也说明字符串不是有效的括号。
代码逻辑
使用栈
- 创建一个空栈,用来存储左括号
- 遍历字符串中的每个字符
- 如果是左括号,就将其入栈
- 如果是右括号,就将栈顶元素出栈,并判断是否和右括号匹配
- 如果不匹配或者栈为空,就返回false,表示字符串不是有效的括号
- 遍历完字符串后,检查栈是否为空
- 如果不为空,就返回false,表示字符串不是有效的括号
- 如果为空,就返回true,表示字符串是有效的括号
具体实现
// 解法1:使用栈 class Solution { public boolean isValid(String s) { Stack<Character> stack = new Stack<>(); for (char c : s.toCharArray()) { // 遇到左括号就入栈 if (c == '(' || c == '[' || c == '{') { stack.push(c); } else { // 遇到右括号就出栈并比较 if (stack.isEmpty()) return false; char top = stack.pop(); if (c == ')' && top != '(') return false; if (c == ']' && top != '[') return false; if (c == '}' && top != '{') return false; } } // 最后判断栈是否为空 return stack.isEmpty(); } }
2.1 解法二 :利用栈+使用ASCII码
思路
这个解法利用了栈的先进后出的特性,遇到左括号就进栈,遇到右括号就出栈配对。它还用了ASCII码的差值来判断是否是匹配的括号。
思路是利用ASCII码的特性,如果两个括号是匹配的,那么它们的ASCII码值之差不会超过2。所以也是使用一个栈来存储左括号,然后遍历字符串中的每个字符,如果是左括号就入栈,如果是右括号就出栈并和栈顶元素比较它们的ASCII码值之差是否小于等于2。如果不是或者栈为空,就说明字符串不是有效的括号。最后遍历完字符串后,还要检查栈是否为空,如果不为空,也说明字符串不是有效的括号。
代码逻辑
使用ASCII码
- 创建一个空栈,用来存储左括号
- 遍历字符串中的每个字符
- 如果是左括号,就将其入栈
- 如果是右括号,就将栈顶元素出栈,并计算它们的ASCII码值之差
- 如果差值大于2或者栈为空,就返回false,表示字符串不是有效的括号
- 遍历完字符串后,检查栈是否为空
- 如果不为空,就返回false,表示字符串不是有效的括号
- 如果为空,就返回true,表示字符串是有效的括号
具体实现
// 解法2:使用ASCII码 class Solution { public boolean isValid(String s) { Stack<Character> stack = new Stack<>(); for (char c : s.toCharArray()) { // 遇到左括号就入栈 if (c == '(' || c == '[' || c == '{') { stack.push(c); } else { // 遇到右括号就出栈并比较ASCII码差值 if (stack.isEmpty()) return false; char top = stack.pop(); if (Math.abs(c - top) > 2) return false; } } // 最后判断栈是否为空 return stack.isEmpty(); } }
2.2 解法三
还有一些其他解法,都差不太多
它用了HashMap来保存左右括号的配对关系,然后用栈来判断是否匹配:
class Solution { public boolean isValid(String s) { //创建一个HashMap,存储左右括号的配对关系 HashMap<Character, Character> map = new HashMap<>(); map.put(')', '('); map.put(']', '['); map.put('}', '{'); //创建一个栈,存储左括号 Stack<Character> stack = new Stack<>(); //遍历字符串 for (int i = 0; i < s.length(); i++) { //获取当前字符 char c = s.charAt(i); //如果是右括号,就判断栈是否为空,以及栈顶元素是否与当前元素匹配 if (map.containsKey(c)) { if (stack.isEmpty() || stack.pop() != map.get(c)) { return false; } } else { //如果是左括号,就入栈 stack.push(c); } } //遍历完后,判断栈是否为空,如果为空,说明所有的括号都匹配了,返回true return stack.isEmpty(); } }
3.总结