典型的用栈解决的问题,所有的有效括号问题都考虑用栈来解决
思路:
左括号入栈等待匹配,匹配成功就出栈,注意栈空和栈满的情况,完全匹配的条件是栈为空,不要忘记字符串为空的特殊测试;
时间复杂度O(n),遍历给定的字符串,但是入栈和出栈的时间复杂度为O(1);空间复杂度O(n),最坏需要将给定的左括号(仅有左括号)全部入栈;
为了快速判断括号的类型,使用hashmap存储每一种括号;
因为最后要做“top==0”的判断,所以top的初始值为0;
维护一个栈需要哪些元素:一个数组(数组的长度为可能累计入栈的元素数+1),一个栈顶指针指向将要入栈元素的存储位置(即当前栈顶元素的索引+1);
出栈操作:栈顶指针--;入栈操作:数组[栈顶指针++]=入栈元素;
思路:
1、暴力:不断replace匹配的括号—>"";每找到一对匹配的字符串就替换为空,然后再从头开始找,直到最后整个字符串被替换为空;时间复杂度O(n^2);
2、栈:左括号就入栈,右括号就和栈顶括号进行匹配;
栈:最近相关性;队列:先来后到;
//手动维护栈:左括号就入栈,右括号就和栈顶括号进行匹配;
//时间复杂度:O(n);空间复杂度:O(n);
char pairs(char a) { //为了快速判断括号的类型,使用hashmap存储每一种括号;
if (a == '}') return '{';
if (a == ']') return '[';
if (a == ')') return '(';
return 0;
}
bool isValid_stack(char* s) {
int n = strlen(s);
if (n % 2 == 1) { //字符串长度必须是偶数
return false;
}
int *stk = (int *)malloc(sizeof(int) * (n+1));
int top = 0; //维护了一个栈顶指针top,top指向下一个字符将要存储的位置,top-1指向栈顶元素,stk是维护的栈;
for (int i = 0; i < n; i++) { //遍历输入的字符串,时间复杂度O(n)
char ch = pairs(s[i]); //获得输入括号的配对括号,或者说判断括号是左括号还是右括号;
if (ch) { //输入右括号
if (top == 0 || stk[top - 1] != ch) {
return false; //返回false的条件:栈为空即右括号字符串的首字符,或者输入括号与栈顶括号不匹配;
}
top--; //匹配成功,通过栈顶指针下移弹出栈顶元素;
} else { //输入左括号,进行入栈操作;
stk[top++] = s[i];
}
}
free(stk);
return top == 0; //所有括号匹配成功,弹出,返回true,如果输入为空字符串也将返回true;
}
测试代码:
void main() {
char *s = "{[()]}";
bool ans = isValid(s);
printf("ans = %d\n", ans);
}