Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

"((()))", "(()())", "(())()", "()(())", "()()()"

只要左括号数大于1就可以添加左括号。只要右括号数大于左括号数就可以添加右括号。

 class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> res; recursive(n, n, "", res); return res;
} void recursive(int n1, int n2, string str, vector<string> &res) {
if (n1 == && n2 == ) {
res.push_back(str);
return;
} if (n1 >= ) {
recursive(n1 - , n2, str + "(", res);
} if (n2 > n1) {
recursive(n1, n2 - , str + ")", res);
}
}
};

网上查了一下,竟然还和Catalan数有关。

通项公式是: \(\frac{(2n)!}{(n+1)!n!}\)

递推公式是 \(C_0=1\ and\ C_{n+1}=\sum\limits^n_{i=0}{C_{i}C_{n-i}}\)

n个+1和n个-1构成2n项\(a_1,a_2,\ldots,a_n\),其部分和满足\(a_1+a_2+\ldots+a_k\ge{}0,0\le{}k\le{}2n\)的序列个数等于第n个Catalan数\(C_n\)。

Valid Parentheses

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.

用了一个栈去实现。当前哪果是右括号,那么栈顶必须是对应的左括号才行。栈为空的话,也只能push左括号。

 class Solution {
public:
bool isValid(string s) {
if (s.empty()) return true; stack<char> st; for (int i = ; i < s.length(); ++i) {
if (st.empty()) {
if (s[i] == '(' || s[i] == '[' || s[i] == '{') st.push(s[i]);
else return false;
} else if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
st.push(s[i]);
} else if (s[i] == ')') {
if (st.top() == '(') st.pop();
else return false;
} else if (s[i] == ']') {
if (st.top() == '[') st.pop();
else return false;
} else if (s[i] == '}') {
if (st.top() == '{') st.pop();
else return false;
} else {
return false;
}
}
return st.empty();
}
};

重构一下:

 class Solution {
public:
bool isValid(string s) {
if (s.empty()) return true; stack<char> st; for (int i = ; i < s.length(); ++i) {
if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
st.push(s[i]);
continue;
} else if (st.empty()) {
return false;
} if (s[i] == ')' && st.top() != '(') return false;
if (s[i] == ']' && st.top() != '[') return false;
if (s[i] == '}' && st.top() != '{') return false;
st.pop();
}
return st.empty();
}
};

用map再重构,可以再简洁一些。

 class Solution {
public:
bool isValid(string s) {
if (s.empty()) return true; map<char, char> pars;
pars[')'] = '(';
pars[']'] = '[';
pars['}'] = '{'; stack<char> st; for (int i = ; i < s.length(); ++i) {
if (pars.find(s[i]) == pars.end()) {
st.push(s[i]);
continue;
} if (st.empty()) {
return false;
} if (st.top() != pars[s[i]]) return false;
st.pop();
}
return st.empty();
}
};

Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

一开始就把思路定在,当碰到一个“(”右括号时,判断当前已经能够消掉的位置。后面也想过把值和位置作一个新的struct push到stack中,但是怎么就是想不到直接在stack中存位置呢。。。。

应该多思考一下和前面Valid Parentheses的关系。

总结思路就在于:

1. 栈顶为"(",当前字符为")",这时就可出栈,同时记录当前消掉的长度;栈如果为空的话表明前面的符号全部被消掉了,所以长度就为i+1. 否则就是pop之后的新栈顶到当前位置的距离。也就是st.pop(); i - st.top();

2. 要检查栈顶,那么st不能为空。

 class Solution {
public:
int longestValidParentheses(string s) {
if (s.empty()) return ; int max = ;
stack<int> st; for (int i = ; i < s.length(); ++i) {
if (st.empty()) {
st.push(i);
} else {
if (s[st.top()] == '(' && s[i] == ')') {
st.pop();
if (st.empty()) {
if (i + > max) max = i + ;
} else if (i - st.top() > max) {
max = i - st.top();
}
} else {
st.push(i);
}
}
} return max;
}
};

第三次写,用栈。

 class Solution {
public:
int longestValidParentheses(string s) {
if (s.empty()) return ;
stack<int> st; int max = ;
for (int i = ; i < s.length(); i++) {
if (st.empty() || s[i] == '(') {
st.push(i);
} else if (s[st.top()] == '(') {
st.pop();
int len = st.empty() ? i + : i - st.top();
if (len > max) max = len;
} else {
st.push(i);
}
} return max;
}
};

这种求longest、maximum之类的题大多数也是可以用dp来做。

dp[i]表示到第i个位置的最长合法串。

1. 初始值都为0. 第一个符号无影响,所以可以从第二个位置开始。

2. 举例说一下dp[i]的更新,假设s="()(()())"。

i=7时,"()(()())";

dp[i-1]=4就是到i-1=6为止的合法串长度,也就是"()(()())";

此时需要检查j=i-dp[i-1]-1= 7-dp[6]-1=2的位置是否为"(","()(()())";

如果是,那么dp[i]=dp[i-1]+2,dp[7]=dp[6]+2=6;

此时还要把j之前的合法串合并起来。dp[i]+=dp[j-1], "()(()())",dp[7]+=dp[1]; dp[7]=8;

所以答案就是8.

 class Solution {
public:
int longestValidParentheses(string s) {
if (s.empty()) return ; vector<int> dp(s.length(), ); int max = ;
for (int i = ; i < s.length(); ++i) {
int j = i - dp[i - ] - ;
if (s[i] == ')' && s[j] == '(') {
dp[i] = dp[i - ] + ;
if (j > ) {
dp[i] += dp[j - ];
}
if (dp[i] > max) max = dp[i];
}
}
return max;
}
};

Leetcode | Parentheses 相关的更多相关文章

  1. leetcode tree相关题目总结

    leetcode tree相关题目小结 所使用的方法不外乎递归,DFS,BFS. 1. 题100 Same Tree Given two binary trees, write a function ...

  2. [LeetCode] [链表] 相关题目总结

    刷完了LeetCode链表相关的经典题目,总结一下用到的技巧: 技巧 哑节点--哑节点可以将很多特殊case(比如:NULL或者单节点问题)转化为一般case进行统一处理,这样代码实现更加简洁,优雅 ...

  3. [leetcode] 根据String数组构造TreeNode,用于LeetCode树结构相关的测试用例

    LeetCode 跟树结构相关的题目的测试用例中大多是通过String数组来构造树.例如{2,#,3,#,4,#,5,#,6},可以构造出如下的树(将树结构逆时针选择90度显示): 6         ...

  4. leetcode String相关

    目录 3无重复字符的最长子串 5最长回文子串 8字符串转换整数(atoi), 9回文数,7整数反转 28实现strStr(), 459重复的子字符串(KMP) 43字符串相乘 71简化路径 93复原I ...

  5. [LeetCode] 二叉树相关题目(不完全)

    最近在做LeetCode上面有关二叉树的题目,这篇博客仅用来记录这些题目的代码. 二叉树的题目,一般都是利用递归来解决的,因此这一类题目对理解递归很有帮助. 1.Symmetric Tree(http ...

  6. LeetCode - 排列相关题目

    1.获取全排列 https://leetcode.com/problems/permutations/submissions/ 按字典序输出: 这里用的是vector<int>,不是引用. ...

  7. leetcode链表相关

    目录 2/445两数相加 综合题(328奇偶链表, 206反转链表, 21合并两个有序链表 ) 92反转链表 II 链表排序(148排序链表, 876链表的中间结点) 142环形链表 II 160相交 ...

  8. leetCode 字符串相关问题

    125. 验证回文串 /* * 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. * 输入: "A man, a plan, a canal: Panama& ...

  9. leetcode 链表相关

    1.给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们 ...

随机推荐

  1. SQL with as

    姓名 课程 分数 张三 语文 张三 数学 张三 物理 李四 语文 李四 数学 李四 物理 先看下面一个嵌套的查询语句 ) 上面的查询语句使用了一个子查询.虽然这条SQL语句并不复杂,但如果嵌套的层次过 ...

  2. v4l2

    参考文章:http://lwn.net/Articles/203924/ 查阅手册:https://linuxtv.org/downloads/v4l-dvb-apis/#INPUT-STATUS

  3. device unauthorized & ANDROID_ADB_SERVER_PORT 问题解决

    最近做安卓开发的时候,碰到了如下两个极品问题,刚开始晕头转向,仔细一研究终于解决了: FAQ1: C:\Users\xxx>adb shelladb: Env var ANDROID_ADB_S ...

  4. mac 下修改Hosts文件

    最近Google网站老是打不开,具体原因大家都明白,不过修改Hosts文件后,就能访问了,也算不上原创,网上一搜就能找到,自己操作记录下,希望有刚接触Mac 系统的童鞋有帮助. 第一步:打开Finde ...

  5. oracle sql developer数据表注释为乱码问题---解决

    参考网址:http://blog.163.com/jackie_howe/blog/static/19949134720121126879265/ 内容: 在windows中创建一个名为“NLS_LA ...

  6. Visual Studio一秒变Node.js IDE

    (此文章同时发表在本人微信公众号"dotNET每日精华文章") 上个月微软发布了一个插件,可以让Visual Studio一秒变身最强大的Node.js开发工具.现在源代码移到了G ...

  7. 51NOD 1623 完美消除 数位DP

    题目描述: 定义数的消除操作为选定[L,R,x],如果数的第L到第R位上的数字都大于等于x,并且这些数都相等,那么该操作是合法的(从低位到高位编号,个位是第一位,百位是第二位……),然后将这些位数上的 ...

  8. Hark的数据结构与算法练习之Bogo排序

    算法说明 Bogo排序是交换排序的一种,它是一种随机排序,也是一种没有使用意义的排序,同样也是一种我觉得很好玩的排序. 举个形象的例子,你手头有一副乱序的扑克牌,然后往天上不停的扔,那么有一定机率会变 ...

  9. VMware Tools安装

    不是每一个程序员都必须玩过linux,只是博主觉得现在的很多服务器都是linux系统的,而自己属于那种前端也搞,后台也搞,对框架搭建也感兴趣,但是很多生产上的框架和工具都是安装在服务器上的,而且有不少 ...

  10. git学习 远程仓库02

    使用远程仓库: 查看当前远程库://克隆后,至少有一个名为 origin 的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库 git remote -v: 并显示所有远程库的地址: 添加远程仓 ...