给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: “()”
输出: true
示例 2:
输入: “()[]{}”
输出: true
示例 3:
输入: “(]”
输出: false
示例 4:
输入: “([)]”
输出: false
示例 5:
输入: “{[]}”
输出: true
方法:利用栈解决
将字符串转变为字符数组,多消耗了空间
class Solution {
public boolean isValid(String s) {
if(s == "" || s.length() == 0){
return true;
}
char[] str = s.toCharArray();
Stack<Character> stack = new Stack<Character>();
int i = 0;
while(i < str.length) {
char f = str[i];
if(!stack.empty()){
Character c = stack.peek();
if(f == ')' && c == '('){
stack.pop();
} else if(f == ']' && c == '['){
stack.pop();
} else if(f == '}' && c == '{'){
stack.pop();
} else {
stack.push(f);
}
} else {
stack.push(f);
}
i++;
}
if(stack.empty()){
return true;
} else {
return false;
}
}
}
复杂度
- 时间复杂度:O(n),每个字符串的字符均遍历一遍,在栈上进行O(1)的push和pop操作
- 空间复杂度:O(n),最坏情况下,所有字符均为左括号,全部入栈,栈深度为n。借助数组操作,空间O(n)。
好理解的代码
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch == '{' || ch == '(' || ch == '[') {
stack.push(ch);
} else if(!stack.isEmpty() && check(ch) == stack.peek()) {
// 字符 c 是右括号
stack.pop();
} else {
// 和最近的左括号(栈顶)不匹配
return false;
}
}
// 是否所有的左括号都被匹配了
return stack.isEmpty();
}
public char check(char ch) {
if(ch == '}') {
return '{';
} else if(ch == ')') {
return '(';
}
return '[';
}
}