题目解析:
给定一个只含有( )*的字符串()算是一组,*)和(*也算是一组,如果没有多余的)或者(就返回true,如果有就返回false
基本思路:
这道题最简单的方法应该就是用贪心算法解决了。
1.首先我们将未匹配的左括号的最大值和最小值看做是两个基数,定义它们的初始最小值是0,(因为有*这个不确定因素,它既可以看作是左右括号,也可以看作是一个空字符串)
2.随着字符串的遍历当我们遇到一个左括号,待匹配的左括号的最大值和最小值都要加一。
3.当我们遇到一个右括号,待匹配的左括号最大值和最小值都必定减少
4.当我们遇到*的时候就有意思了,它可能在接下来的配对中担任左括号也有可能担任右括号还有可能只是一个空字符串,因此此时待匹配的左括号最大值加一,最小值减一
5.那么什么时候输出结果呢,当我们匹配右括号时,发现前面已经没有左括号与之匹配了此时就可以放心大胆的输出false了,因为无论后面有什么也不管这个多出来的右括号的事了,这个右括号注定是多余的。当循环完成发现没有多余的左括号,或者右括号就可以输出true了,*可以看成空字符串因此无需考虑
复杂度分析
时间复杂度:O(n),其中 nn是字符串 s的长度。需要遍历字符串一次。
空间复杂度:O(1)。
代码实现:
class Solution {
public boolean checkValidString(String s) {
//定义未匹配的左括号的最大值和最小值
int max = 0;
int min = 0;
int len = s.length();
//通过长度遍历字符串
for(int i = 0;i<len;i++){
//取出字符串中的每个符号
char c = s.charAt(i);
//如果发现‘(’,那么未匹配的左括号最大值和最小值都+1
if(c == '('){
max++;
min++;
//如果发现‘)’,那么未匹配的左括号的最大值和最小值都减一
}else if(c == ')'){
//当未匹配的左括号最小值为0时,不应将最小值继续减少,以确保最小值非负。
min = Math.max(min-1,0);
max--;
//当未匹配的左括号最大值为负时,此时说明已经没有左括号可与之匹配因此此时可以直接输出false
if(max<0){
return false;
}
//当遇到*的时候就是最大值加一最小值减一
}else{
min = Math.max(min-1,0);
max++;
}
}
return min==0;
}
}