给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
-
左括号必须用相同类型的右括号闭合。
-
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()" 输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]" 输出:false
示例 4:
输入:s = "([)]" 输出:false
示例 5:
输入:s = "{[]}"
输出:true
2.思路分析
如果学过数据结构,那么看到这个题一定会第一时间想到栈,是的,这个题就是标准的使用栈来解决;
首先,如果字符串的长度为奇数,可以直接判断该字符串不符合题意,直接返回“false”;
当遇到左括号如‘[’,‘{‘,’(‘时,就将他们压入栈中,当遇到右括号时,我们需要判断当前的右括号与栈顶的元素是否匹配,如果匹配,则将栈顶元素弹出栈,并进行下轮循环;
依次执行,直到遍历完最后一个元素,返回“true”。
3.解题代码解法一:(不使用STL,自己写的)
如果不会STL可以使用如下方法,但是要自己建栈,自己写所有关于栈的操作;
#includeusing namespace std; #include #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容器)
#includeusing namespace std; #include #include class Solution { public: bool isValid(string s) { stack 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 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字符串,第二种执行速度相对较快。



