Valid Parentheses 括号匹配问题
题目:
Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.
Example 1:
Input: “()”
Output: true
(源于Leetcode 第20 题)
解析:
本题本质上就是括号匹配问题。值得注意的此问题的输入仅仅只有三种括号,因此此问题相对含其他字符的括号匹配问题没那么复杂。下面提供几种解法(from Leetcode discussion)
解法一:一种普遍做法使用栈,就是遇到左括号入栈,当遇到右括号时,依次出栈看是否存在匹配的左括号,等完成后,如果栈为空的话,那么说明括号是完全匹配的,否则就是无效的。
我们同时还能注意得到,如果遇到右括号,则栈顶的元素必然是左括号,那么就只需和栈顶的元素匹配即可
下面提供一种java的代码
public boolean isValid(String s) {
Stack<Character> sta = new Stack<Character>();
char[] value = s.toCharArray();
for (char c : value) {
if (c == '(' || c == '{' || c == '[') {
sta.push(c);// 左括号进栈
} else if (c == ')') {
if (!sta.empty()) {
char a = sta.pop();
if (a == '(') {//栈顶是否匹配
continue;
} else {
return false;
}
}
} else if (c == ']') {
if (!sta.empty()) {
char a = sta.pop();
if (a == '[') {
continue;
} else {
return false;
}
}
} else if (c == '}') {
if (!sta.empty()) {
char a = sta.pop();
if (a == '{') {
continue;
} else {
return false;
}
}
}
}
if (sta.empty())
return true;
else
return false;
}
解法二:设想如果括号是符合要求的,则两个括号必然是对称的,如(){}和({})。又如解法一所说,右括号遇到的栈顶必然是左括号,那么当遇到左括号时,则将其对应的右括号放入栈,则遇到右括号时,直接看是否与栈顶元素相等即可。和解法一相似
下面提供java的代码
public boolean isValid(String s) {
Stack<Character> stack = new Stack<Character>();
for (char c : s.toCharArray()) {
if (c == '(')
stack.push(')');
else if (c == '{')
stack.push('}');
else if (c == '[')
stack.push(']');
else if (stack.isEmpty() || stack.pop() != c)
return false;
}
return stack.isEmpty();
}
解法三 :我们还能运用String类里面的replace方法来解决。通过将括号换为空,那么最后如果长度为零的话,那么括号就是符合要求的。
下面提供java代码
public boolean isValid(String s) {
if (s.trim().length() == 0) return true;
int currentLen = -1;
while (currentLen != s.length()) {
currentLen = s.length();
s = s.replace("()", "").replace("[]", "").replace("{}", "");
}
return s.length() == 0;
}
此解法虽然代码简洁,不过速度很慢。原因在于replace()方法。从该方法的源码可知,该方法至少对字符串扫描一次,最多两次(第一次对字符串扫描是否存在要替换的字符,存在则进行第二次扫描进行替换,结果放入新的字符串中)。意味着替代使用三次该函数,最坏需要扫描字符串6次。而以上两种解法仅需扫描1次