题目
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
提示:
1 <= s.length <= 104
s 仅由括号 '()[]{}' 组成
解题思路1
使用Map枚举所有括号的键值对,然后循环字符串,利用数组缓存字符串中未匹配到的数据,代码实现如下:
package leetcode;
import java.util.*;
/**
* 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
*
* 有效字符串需满足:
*
* 左括号必须用相同类型的右括号闭合。
* 左括号必须以正确的顺序闭合。
*
*
* 示例 1:
*
* 输入:s = "()"
* 输出:true
* 示例 2:
*
* 输入:s = "()[]{}"
* 输出:true
* 示例 3:
*
* 输入:s = "(]"
* 输出:false
* 示例 4:
*
* 输入:s = "([)]"
* 输出:false
* 示例 5:
*
* 输入:s = "{[]}"
* 输出:true
*
*/
public class ValidParenthesesTest {
public static void main(String[] args) {
final long startTime = System.currentTimeMillis();
System.out.println(isValid("([])[]"));
final long endTime = System.currentTimeMillis();
System.out.println("耗时 " + (endTime - startTime) + " ms");
}
private static Map<String, String> keyMap = new HashMap<String, String>() {{
put(")", "(");
put("]", "[");
put("}", "{");
}};
private static boolean isValid(final String s) {
final List<String> cacheList = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
final String currentString = String.valueOf(s.charAt(i));
if (keyMap.containsKey(currentString)) {
if (cacheList.size() > 0) {
final int maxIndex = cacheList.size() - 1;
if (cacheList.get(maxIndex).equals(keyMap.get(currentString))) {
cacheList.remove(maxIndex);
} else {
cacheList.add(currentString);
}
} else {
// 如果开始就是以右括号开头的直接调出循环
cacheList.add(currentString);
break;
}
} else {
cacheList.add(currentString);
}
}
return cacheList.size() == 0;
}
}
解题思路2
思路1中已经成功执行,但是发现一个问题,这里面每次都只是操作数组的最后一个元素,和数据结构中的栈的原理比较类似,于是尝试用栈来解决
package leetcode;
import java.util.*;
/**
* 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
*
* 有效字符串需满足:
*
* 左括号必须用相同类型的右括号闭合。
* 左括号必须以正确的顺序闭合。
*
*
* 示例 1:
*
* 输入:s = "()"
* 输出:true
* 示例 2:
*
* 输入:s = "()[]{}"
* 输出:true
* 示例 3:
*
* 输入:s = "(]"
* 输出:false
* 示例 4:
*
* 输入:s = "([)]"
* 输出:false
* 示例 5:
*
* 输入:s = "{[]}"
* 输出:true
*
*/
public class TestStackRefs {
public static void main(String[] args) {
final long startTime = System.currentTimeMillis();
System.out.println(isValid("([])[]"));
final long endTime = System.currentTimeMillis();
System.out.println("耗时 " + (endTime - startTime) + " ms");
}
private static Map<Character, Character> keyMap = new HashMap<Character, Character>() {{
put(')', '(');
put(']', '[');
put('}', '{');
}};
private static boolean isValid(final String s) {
// 如果字符串长度为奇数时,则直接返回false
if (s.length() % 2 == 1) {
return false;
}
final Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
final char currentChar = s.charAt(i);
if (keyMap.containsKey(currentChar)) {
if (stack.isEmpty()) {
// 如果开始就是以右括号开头的直接调出循环
stack.push(currentChar);
break;
} else {
if (stack.peek().equals(keyMap.get(currentChar))) {
stack.pop();
} else {
stack.push(currentChar);
}
}
} else {
stack.push(currentChar);
}
}
return stack.empty();
}
}