题目
思路:
- 明确目标:用栈实现:
- 搞清楚要怎么操作:即搞清楚有几种返回false类型
- 栈中只保存左括号,当遍历到右括号时比较是否为栈首元素对应的右括号,若是则弹出栈顶元素(栈顶指针下移),若不是则返回false,直到字符串遍历结束/栈元素为空,前者若栈元素正好为空则返回true/后者若字符串未遍历完也返回false
重难点1:如何规划代码布局
- 首先声明变量
- 第二步设置for循环遍历字符串
- 第三部在循环内开始做判断:if tempchar为左括号,则入栈,为右括号则不入
- 第三步在循环内继续判断:else if tempchar为右括号时的两种情况①不能与栈顶元素匹配 (第二种情况),返回false ②此时栈中已没有元素(第三种情况),返回false ③可以匹配则弹出栈顶元素
- 第四步在循环结束:通过栈顶指针大小判断最终输出
重难点2:如何实现第二种情况的判断
//使用辅助函数判断输出
int cur(char tempchar,char*stack,int stacktop)
{
switch(tempchar)
{
case ')':
return stack[stacktop]=='(';
case ']':
return stack[stacktop]=='[';
case '}':
return stack[stacktop]=='{';
}
return 0;
}
、、、
else if(cur(tempchar,stack,stacktop)==false||stacktop==0)return false;
最终代码:
int cur(char tempchar,char*stack,int stacktop)
{
switch(tempchar)
{
case ')':
return stack[stacktop]=='(';
case ']':
return stack[stacktop]=='[';
case '}':
return stack[stacktop]=='{';
}
return 0;
}
bool isValid(char * s){
int slen=strlen(s);
char stack[10000]=" ";//开辟栈空间
int stacktop=0;
// //入栈
// for(int i=0;i<slen;i++)
// {
// stack[i]=s[i];
// stacktop++;//始终注意栈顶指针指向为空
// }
for(int i=0;i<slen;i++)
{
char tempchar=s[i];//判断char是否入栈,直接解决(问题一):为右括号
//若此时char为左括号则入栈
if(tempchar=='('||tempchar=='['||tempchar=='{')
{
stack[++stacktop]=tempchar;//始终注意栈顶指针指向为空
}
//若此时char是右括号,但不能与左括号配对(问题二)/栈中已无元素(问题三)
else if(cur(tempchar,stack,stacktop)==false||stacktop==0)return false;
else stacktop--;
}
if(stacktop==0)return true;
else return false;
}
时间/空间复杂度O(n)
注意易错点
1:不需要所有元素进栈
2:注意char中下标不能出现负数,否则越界,编写错误,所以令栈顶指针先加一后赋值(比较元素时不需要对栈顶指针-1)
简化代码(另一种想法:只令右括号相应的左括号入栈,栈元素与字符串元素进行比较)
bool isValid(char * s){
char stack[10000]=" ";//开辟栈空间
char t;
int stacktop=0;
int i;
while(s[i]!='\0')
{
//若此时char为左括号则对应右括号入栈
if(s[i]=='('||s[i]=='['||s[i]=='{')
{
if(s[i]=='(')t=')';
if(s[i]=='[')t=']';
if(s[i]=='{')t='}';
stacktop++;
stack[stacktop]=t;
// stack[stacktop++]=t;
}
//若此时char是右括号,但不能与左括号配对(问题二)
else{
if(stack[stacktop]!=s[i])return false;
else stacktop--;
}
i++;
}
//问题三
if(stacktop==0)return true;
else return false;
}
简洁好理解