问题描述
我正在尝试尝试此问题。 https://leetcode.com/problems/valid-parentheses/。但是,如果在第二个for循环中可以比较s.charat(i)和stack.pop(),我感到困惑。
基本上,我的方法是这样。将整个字符串推入堆栈,然后使用stack.charat(i)遍历堆栈的前半部分,然后使用stack.pop()将其与后半部分进行比较。我只是想知道代码中可能出什么问题,因为当我期望一个真值时我得到一个假值。我只是想了解我的概念是否存在缺陷?
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
boolean done = false;
if(s.length() < 2)
return true;
for(int i = 0; i < s.length(); i++){
stack.push(s.charat(i));
}
for(int i = 0; i < s.length()/2; i++){
if(s.charat(i) == stack.pop())
done = true;
}
return done;
}
}
解决方法
虽然您的代码可能适用于诸如“ {([])}
”和“ (())
”之类的字符串,但是您假设这些字符串是对称的。诸如“ {()[]}
”之类的有效输入将不会传递给您的代码,因为它不是对称的。修改您的代码以解决不对称问题。
提示:当字符是结束字符(例如“)”,“}”和“]”)时,可能会弹出2个元素。
您应该检查字符串中的括号是否匹配:对于'('
,有一个匹配的')'
。但是,请注意,字符'('
不等于字符')'
。
您的代码正在检查字符串是否与某个模式匹配,该模式的下半部字符串是后半部字符串,例如{[))[{
。换句话说,您正在检查输入是否为 palindrome 。
您应该采取的方法是仅将起始括号存储在堆栈中:
for(int i = 0; i < s.length(); i++){
if s.charAt(i) is an open bracket:
stack.push(s.charAt(i));
else:
"pop" a character from stack
if it's '(' make sure that s.charAt(i) is ')'
if it's '[' make sure that s.charAt(i) is ']'
if it's '{' make sure that s.charAt(i) is '}'
}
,
您的代码首先迭代到字符串的中间,然后填充堆栈,然后从中间到末尾并弹出堆栈。换句话说,您隐式地假设有效字符串的前半部分是各种类型的开括号,第二个是其相应的闭括号(例如([])
或{[()]}
)。但是,这些并不是唯一有效的字符串-没有限制,只要一对匹配,就不能在右括号后面加上开括号-例如(()())
是有效字符串
您应该对字符串进行迭代,而不是对字符串中的位置进行假设,并且对于每个字符,如果它是一个开括号,请将其推入堆栈,如果它是一个闭合括号,则将堆栈弹出并进行比较:
private static final Map<Character,Character> PARENS = new HashMap<>();
static {
PARENS.put('(',')');
PARENS.put('[',']');
PARENS.put('{','}');
}
public static boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (PARENS.containsKey(ch)) {
stack.push(ch);
} else {
if (stack.isEmpty()) {
return false;
}
char match = stack.pop();
if (ch != PARENS.get(match)) {
return false;
}
}
}
return stack.isEmpty();
}