提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
- 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
- 有效字符串需满足:左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Stack解决
- 思路:判断当前字符串的长度是不是偶数,然后再讲括号存放到哈希中,在进行循环,使用栈来检查括号的匹配关系。当遇到左括号时,将其压入栈中;当遇到右括号时,弹出栈顶元素并检查是否匹配
public boolean isValid(String s) {
// 如果字符串的长度是奇数,那么他不可能是有效的括号
if (s.length() % 2 != 0) {
return false;
}
//用哈希存放对应的关系
Map<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)) {
// 弹出栈顶元素,如果栈为空,用 '#' 表示
char teop = stack.isEmpty() ? '#' : stack.pop();
if (map.get(c) != teop) {
return false;
}
} else {
// 如果当前字符是左括号,存放到栈 中
stack.push(c);
}
}
// 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
return stack.isEmpty();
}
二、isValidArray数组模拟栈
- 思路:使用字符数组模拟栈,然后再使用哈希存放括号的对应关系,再进行循环,使用数组模拟栈来检查括号的匹配关系。当遇到左括号时,将其压入数组模拟栈中;当遇到右括号时,弹出栈顶元素并检查是否匹配,最终,如果栈为空,表示所有括号都匹配成功
解法一
public static boolean isValidArray(String s) {
if (s.length() % 2 != 0) {
return false;
}
// 使用字符数组模拟栈
char[] stack = new char[s.length()];
int index = 0;
// 使用 HashMap 存储括号的对应关系
Map<Character, Character> map = new HashMap<>();
map.put(')', '(');
map.put(']', '[');
map.put('}', '{');
// 遍历输入的字符串
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
// 如果是右括号,检查栈顶元素是否匹配
char top = (index == 0) ? '#' : stack[--index];
if (map.get(c) != top) {
return false;
}
} else {
// 如果是左括号,将其推入栈
stack[index++] = c;
}
}
// 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
return index == 0;
}
解法二
public static boolean isValidChar(String s) {
//判断是不是奇数
if (s.length() % 2 != 0) {
return false;
}
// 使用字符数组模拟栈
char[] stack = new char[s.length()];
int top = 0;
// 遍历输入的字符串
for (char c : s.toCharArray()) {
if (c == ')' && top > 0 && stack[top - 1] == '(' ||
c == ']' && top > 0 && stack[top - 1] == '[' ||
c == '}' && top > 0 && stack[top - 1] == '{') {
// 如果当前字符是右括号且栈非空且栈顶元素与之匹配,则出栈
top--;
} else {
// 否则,将当前字符压入栈
stack[top++] = c;
}
}
// 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
return top == 0;
}
二、双端队列
- 思路:
- 检查输入字符串的长度是否为偶数,因为有效的括号匹配必须是成对的,如果长度为奇数,直接返回false
- 创建一个双端队列(Deque)来模拟栈的行为。在Java中,LinkedList实现了Deque接口,因此可以用它来实现栈
- 使用HashMap存储括号的对应关系,其中键是右括号,值是对应的左括号。这样可以方便地查找匹配关系
- 遍历输入字符串的每个字符
- 检查栈是否为空。如果为空,表示所有括号都成功匹配,返回true;否则,返回false
public static boolean isValidDeque(String s) {
if (s.length() % 2 != 0) {
return false;
}
// 使用双端队列模拟栈
Deque<Character> stack = new LinkedList<>();
// 使用 HashMap 存储括号的对应关系
Map<Character, Character> map = new HashMap<>();
map.put(')', '(');
map.put(']', '[');
map.put('}', '{');
// 遍历输入的字符串
for (char c : s.toCharArray()) {
if (map.containsKey(c)) {
// 如果是右括号,检查栈顶元素是否匹配
char top = stack.isEmpty() ? '#' : stack.poll();
if (map.get(c) != top) {
return false;
}
} else {
// 如果是左括号,将其推入栈
stack.push(c);
}
}
// 最终,如果栈为空,表示所有括号都匹配成功,返回 true;否则,返回 false
return stack.isEmpty();
}