#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <unordered_set>
using namespace std;
int maxDepth(string s) {
int res = 0, cnt = 0;
for(char c :s)
{
if('(' == c)
{
++cnt;
}
if(')' == c)
{
--cnt;
}
res = max(res,cnt);
}
return res;
}
int minAddToMakeValid(string s) {
int left = 0, right = 0;
for(char c:s)
{
if(c == '(')
{
++right;
}
if(c == ')')
{
if(right > 0) --right;
else ++left;
}
}
return left + right;
}
bool isValid(const string s)
{
stack<char>st;
for(char c : s)
{
if(c == '(')
{
st.push(')');
}
else if(c == '{')
{
st.push('}');
}
else if(c == '[')
{
st.push(']');
}
else if(st.empty() || st.top() != c)
{
return false;
}
else
{
st.pop();
}
}
return st.empty();
}
string minRemoveToMakeValid(string s) {
stack<int>st;
unordered_set<int>removeIndex;
for(int i = 0 ;i < s.size();++i)
{
char c = s[i];
if(c == '(')
{
st.push(i);
}
else if(c == ')')
{
if(st.empty())removeIndex.insert(i);
else st.pop();
}
}
while(!st.empty())
{
removeIndex.insert(st.top());
st.pop();
}
string res = "";
if(!removeIndex.empty())
{
for(int j = 0;j < s.size(); ++j)
{
if(removeIndex.find(j)!=removeIndex.end())
{
continue;
}
res.push_back(s[j]);
}
}
return res;
}
int scoreOfParentheses(string s) {
stack<int>st;
st.push(0);
for(char c : s)
{
if(c == '(')
{
st.push(0);
}
else
{
int v = st.top();
st.pop();
int w = st.top();
st.pop();
st.push(w+max(2*v,1));
}
}
return st.top();
}
int longestValidParentheses(string s) {
int res = 0;
stack<int>st;
st.push(-1);
for(int i = 0;i < s.size(); ++i)
{
char c =s[i];
if(c == '(')
{
st.push(i);
}
else
{
st.pop();
if(st.empty())st.push(i);
else
res = max(res, i - st.top());
}
}
return res;
}
void dfs(int left, int right, string level,vector<string>&res)
{
if(left > right)return;
if(left == 0 && right == 0)res.emplace_back(level);
if(left > 0)dfs(left - 1, right,level + "(",res);
if(right > 0)dfs(left,right - 1,level+")",res);
return ;
}
vector<string> generateParentheses(int n)
{
vector<string>res;
dfs(n,n,"",res);
return res;
}
void print(const vector<int>& nums)
{
for(auto num:nums)
{
cout << num << " ";
}
cout << endl;
}
void print(const vector<string>&s)
{
for(auto str:s)
{
cout << str << " ";
}
cout << endl;
}
vector<int> diffWaysToCompute(string expression) {
vector<int>res;
for(int i = 0; i < expression.size(); ++i)
{
char c = expression[i];
if(c == '+'|| c == '-' || c == '*')
{
auto leftV = diffWaysToCompute(expression.substr(0,i));
auto rightV = diffWaysToCompute(expression.substr(i + 1));
for(int left : leftV)
{
for(int right:rightV)
{
int tmp = 0;
if(c == '+')
{
tmp = left + right;
}
else if(c == '-')
{
tmp = left - right;
}
else
{
tmp = left * right;
}
res.push_back(tmp);
}
}
}
}
if(res.size() == 0)
{
res.push_back(stoi(expression));
}
return res;
}
int main()
{
//LeetCode1614
string s = "(1+(2*3)+((8)/4))+1";
cout << maxDepth(s) << endl;
//LeetCode921
string s0 = "(((";
cout << minAddToMakeValid(s0) << endl;
//LeetCode20
string s1 = "{[]}";
cout << isValid(s1) << endl;
//LeetCode1249
string s2 ="a)b(c)d";
cout << minRemoveToMakeValid(s2) << endl;
//LeetCode856
string s3="(()(()))";
cout << scoreOfParentheses(s3) << endl;
//LeetCode32
string s4 = ")()())";
cout << longestValidParentheses(s4) << endl;
//LeetCode22
int n = 3;
print(generateParentheses(n));
//LeetCode241
string expression = "2*3-4*5";
print(diffWaysToCompute(expression));
return 0;
}