1.题目描述
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
-
左括号必须用相同类型的右括号闭合。
-
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
2.思路分析
如果学过数据结构,那么看到这个题一定会第一时间想到栈,是的,这个题就是标准的使用栈来解决;
首先,如果字符串的长度为奇数,可以直接判断该字符串不符合题意,直接返回“false”;
当遇到左括号如‘[’,‘{‘,’(‘时,就将他们压入栈中,当遇到右括号时,我们需要判断当前的右括号与栈顶的元素是否匹配,如果匹配,则将栈顶元素弹出栈,并进行下轮循环;
依次执行,直到遍历完最后一个元素,返回“true”。
3.解题代码
解法一:(不使用STL,自己写的)
如果不会STL可以使用如下方法,但是要自己建栈,自己写所有关于栈的操作;
#include<iostream>
using namespace std;
#include<string>
#define MaxSize 50
typedef char ElemType;
typedef struct {
ElemType s[MaxSize];
int top;
}SqStack;
//初始化
void InitStack(SqStack& S)
{
S.top = -1;
}
//判断栈是否为空
bool StackEmpty(SqStack S)
{
if (-1 == S.top)
return true;
else
return false;
}
void push(SqStack &S, char s)
{
S.s[++S.top] = s;
}
char pop(SqStack& S)
{
return S.s[S.top--];
}
bool Emepy(SqStack S)
{
if (-1 == S.top)
return true;
else
return false;
}
bool isValid(SqStack S,string s)
{
for (int i = 0; i < s.length(); i++)
{
if ('[' == s[i] || '{' == s[i] || '(' == s[i])
{
push(S, s[i]);
}
if (']' == s[i] || '}' == s[i] || ')' == s[i])
{
if ('[' == S.s[S.top] && ']' == s[i])
char Top = pop(S);
if ('{' == S.s[S.top] && '}' == s[i])
char Top = pop(S);
if ('(' == S.s[S.top] && ')' == s[i])
char Top = pop(S);
}
}
return Emepy(S);
}
int main()
{
SqStack S;
InitStack(S);
bool ret;
string s = "{}[]({})";
ret = isValid(S,s);
cout << ret << endl;
return 0;
}
解法二:(参考别人思路,用STL容器)
#include<iostream>
using namespace std;
#include<string>
#include<stack>
class Solution {
public:
bool isValid(string s) {
stack<char>buffer;
for (int i = 0; i < s.size(); i++)
{
if (buffer.empty())
{
buffer.push(s[i]);
continue;
}
char top = buffer.top();
if (s[i] == '}' && top == '{')
{
buffer.pop();
continue;
}
else if (s[i] == ']' && top == '[')
{
buffer.pop();
continue;
}
else if (s[i] == ')' && top == '(')
{
buffer.pop();
continue;
}
buffer.push(s[i]);
}
return buffer.empty();
}
};
void test01()
{
Solution So;
bool ret;
ret = So.isValid("[]{()}{}");
cout << ret << endl;
}
int main()
{
test01();
return 0;
}
解法三:(别人的做法)
class Solution {
public:
bool isValid(string s) {
stack<char> st;
char t;
for (char &c: s) {
if (c == '(' || c == '[' || c == '{')
st.push(c);
else {
if (st.empty())
return false;
t = st.top();
st.pop();
if (c == ')' && t != '(')
return false;
if (c == ']' && t != '[')
return false;
if (c == '}' && t != '{')
return false;
}
}
return st.empty();
}
};
4.新知识点
-
stack容器:
-
stack stk;` //stack采用模板类实现, stack对象的默认构造形式
-
stack(const stack &stk);
//拷贝构造函数 -
stk.push(elem);
//向栈顶添加元素 -
stk.pop();
//从栈顶移除第一个元素 -
stk.top();
//返回栈顶元素 -
stk.empty();
//判断堆栈是否为空 -
stk.size();
//返回栈的大小
-
-
for(char c :s)和for(char &c : s)的操作区别
相同点:
都是遍历整个字符串
都相当于C++的:
for( int i = 0; i < s.length(); i++){}
不同点:
for(char c :s)
复制一个s字符串再进行遍历操作,不会改变字符串s的值;for(char &c : s)
直接使用s字符串进行遍历操作,使用了引用类型,直接引用原字符串进行遍历操作,不需要赋值,但是对c进行赋值时也会改变原来的值;
不过,由于第一种需要先复制一遍s字符串,第二种执行速度相对较快。