目录
1.题目要求
3.代码分部讲解
(1)第一部分
(2)第二部分
4.总结
题目要求
给定一个只包括 ' ( ' ,' ) ' ,' { ' ,' } ' ,' [ ' ,' ] ' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "( )"
输出:true
示例 2:输入:s = "( )[ ]{ }"
输出:true
示例 3:输入:s = "( ]"
输出:false
示例 4:输入:s = "( [ ) ]"
输出:false
示例 5:输入:s = "{ [ ] }"
输出:true
提示:
1 <= s.length <= 104
s 仅由括号 '()[]{}' 组成来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-parentheses
这道题目用 “栈” 的方法和思想会更容易理解同时可以更简单的解决这个问题。
题目理解以及思路分析
(一) 这个题目就是将括号进行配对,因此便有配对成功与失败两种情况。
(二) 根据题意可以看出 括号的长度必须为 偶数 ,否则一定是配对失败。
(三) 右括号前必须有相对应的左括号,这样才可能配对成功;如果右括号前面没有相对应的左括号则其一定配对不成功。
(四) 为了使得配对的思路清晰同时保证不乱,我们采用“栈”的方法,即将其对应的左括号当作“栈顶”,与后面的右括号进行判断,如果左右括号对应则二者抵消,否则判定错误。
为了更好便于大家理解,我做了上面的思路图解,通过图片我们可以明白 “栈” 的思想对于这道题目的使用。希望大家可以好好的消化理解。(图片有些模糊)
代码分部讲解
通过上面的思路分析以及对题目的理解,下面我们将进行代码的实现
第一部分
//定义一个函数,对左右括号进行一个判断
char Pan(char a)
{
//如果是右括号,则我们返回其对应的左括号
if(a == ')')
return '(';
if(a == ']')
return '[';
if(a == '}')
return '{';
//如果是左括号,我们返回 0
else
return 0;
}
这一部分的目的其实是为下面的判断做铺垫。
第二部分
bool isValid(char * s){
int top = 0,n,i,b;
char ch;
n = strlen(s); //求出字符串的长度
int count[n]; //定义一个数组————栈
if(n % 2 == 1) //首先进行判断,如果字符串的长度为 奇数,则无论如何都无法配对成功
return false;
for(i = 0;i < n;i ++)
{
ch = Pan(s[i]);
if(ch)
{
if(top == 0||count[top - 1] != ch)
return false;
top--;
}
else
{
b = top++;
count[b] = s[i];
}
}
return top == 0;
}
对于这部分的代码,简单的部分我已经将解释放在了里面,下面我们将抽出来重点的部分着重讲解:
这一部分特别重要,同时也不好理解!!!希望大家认真看完
for(i = 0;i < n;i ++) { ch = Pan(s[i]); if(ch) { if(top == 0||count[top - 1] != ch) return false; top--; } else { b = top++; count[b] = s[i]; } }
首先进行 for 循环,这个很容易理解,因为我们要进行遍历,然后才能进行配对。
调用 Pan 函数 ,这个时候前面我们定义的函数的作用就出来了,我们接着往下看。
调用函数后,我们就开始判断了,看看是左括号还是右括号,通过上面我们定义的函数可以知道如果此时 s[ i ] 是 右括号,则返回的函数值为其对应的 左括号;如果此时 s[ i ] 是 左括号,则返回的函数值为 0 。
if(ch) { if(top == 0||count[top - 1] != ch) return false; top--; }
执行这一步说明此时 Pan 函数返回的其对应的 左括号,也就是说其原数据为 右括号,根据上面的解释图解我们可以得知,如果是 右括号 我们必须进行配对,因此:
if(top == 0||count[top - 1] != ch) return false; top--;
这一步便是配对的过程,如果 top 为 0(即栈为空),或者栈的上一个栈顶不等于此时Pan函数的返回值,则说明配对失败。
如果配对成功,则 top--,即弹出栈内(抵消)。
这个时候很多读者不理解最后一个
count[top - 1] != ch
首先我们知道如果原字符串里是右括号 则 Pan 函数返回的是其对应的左括号,因此如果栈(count)上一个栈顶与其不相等就意味着二者不能配对成功。(希望大家好好理解这一点)
讲完了一种情况,接下来还剩下一种情况:Pan 函数返回值为 0 的情况。
else { b = top++; count[b] = s[i]; } }
明白了上面的讲解,那这一部分就显得很好理解了,原字符串如果是 右括号 我们便进行判断,如果是 左括号,我们就直接 压入栈内,等待与其配对的括号出现。
第三部分
附上完整的代码
char Pan(char a)
{
if(a == ')')
return '(';
if(a == ']')
return '[';
if(a == '}')
return '{';
else
return 0;
}
bool isValid(char * s){
int top = 0,n,i,b;
char ch;
n = strlen(s);
int count[n];
if(n % 2 == 1)
return false;
for(i = 0;i < n;i ++)
{
ch = Pan(s[i]);
if(ch)
{
if(top == 0||count[top - 1] != ch)
return false;
top--;
}
else
{
b = top++;
count[b] = s[i];
}
}
return top == 0;
}
总结
本题主要是用“栈”的思想来解决,用的十分巧妙的地方是,左右两括号配对成功后便弹出栈内,也就是抵消,这样减少了数据处理的困难程度。