本文介绍两道Parentheses的题,解法都与stack相关
先是入门题20.Valid Parentheses
Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.
Example 1:
Input: “()”
Output: true
Example 2:
Input: “()[]{}”
Output: true
Example 3:
Input: “(]”
Output: false
Example 4:
Input: “([)]”
Output: false
Example 5:
Input: “{[]}”
Output: true
这道题的题意就是给一些由(、)、{、}、[、]组成的字串,判断其是否是合法的
解法如图:
首先要知道stack是先进后出的,那么每次输入一个新的样例,若是括号的左部,则将其push近栈中,而若是括号的右部,且与栈顶搭配,则将栈顶元素pop出来(右部也不需要push进),如 {[]} 的第三个步骤,而若是与栈顶不匹配,则需要将其push进,如 ([)] 的第三步
于是就可以得到下列代码:
class Solution {
public:
bool isValid(string s) {
map<char, char> m;
m[')'] = '(';
m['}'] = '{';
m[']'] = '[';
stack<char> st;
for (int i = 0; i < s.length(); ++i)
{
if (st.empty() || st.top() != m[s[i]])
{
st.push(s[i]);
}
else st.pop();
}
if (st.empty()) return true;
return false;
}
};
如果再想一下,如上面的 ([)] ,其实在把’)’push进去的时候就应该知道,后面不管是什么,都不可能是valid的,因此可以进行剪枝优化:
class Solution {
public:
bool isValid(string s) {
map<char, char> m;
m[')'] = '(';
m['}'] = '{';
m[']'] = '[';
stack<char> st;
for (int i = 0; i < s.length(); ++i)
{
if (st.empty() || s[i] == '(' || s[i] == '{' || s[i] == '[')
{
st.push(s[i]);
}
else
{
if(m[s[i]] == st.top())
st.pop();
//直接返回错误
else return false;
}
}
if (st.empty()) return true;
return false;
}
};
第二个进阶版:32. Longest Valid Parentheses
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”
Example 2:
Input: “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”
这个的题意为字串完全由(、)组成(也就是没有[、{这些)从所给的字串中,找到最长的合法串
我在解找到题的时候用了个小技巧,push、配对的步骤和上题是一样的,但一旦判断出新字符与栈顶元素配对,那么将原字符串中对应位置的两个字符全部置空格
例如原串是)()()(:
最后遍历得到最长的连续空格数,即为所求。下面是代码:
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> st;
for (int i = 0; i < s.length(); ++i)
{
//只有(,只需判断一个即可
if (st.empty() || s[i] == '(')
{
st.push(i);
}
else
{
//若配对,则将原串中两个位置都置空格,同时pop栈顶
if (s[st.top()] == '(')
{
s[i] = ' ';
s[st.top()] = ' ';
st.pop();
}
}
}
int res = 0, cnt = 0;
for (int i = 0; i < s.length(); ++i)
{
if (s[i] == ' ')
{
cnt++;
}
else
{
if (res < cnt) res = cnt;
cnt = 0;
}
}
if (res < cnt) res = cnt;
return res;
}
};