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. Java for LeetCode 199 Binary Tree Right Side View

    Given a binary tree, imagine yourself standing on the right side of it, return the values of the nod ...

  2. DisJSet:Find them, Catch them(POJ 1703)

    抓住他们! 题目大意:两个黑社会帮派,互相打架,现在你很多条信息,要你确定两个人是否属于不同帮派 这题很有趣,题目不是直接给你两个人是否是一个帮派的,他给你的是不同帮派的,也就是给你很多个不同的要你找 ...

  3. codeforces 488A. Giga Tower 解题报告

    题目链接:http://codeforces.com/problemset/problem/488/A 题目意思:给出一个数a,范围是[-10^9, 10^9],问它最少需要加的一个正整数 b 是多少 ...

  4. hdu 1232 畅通工程 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232 并查集入门题.最近在学并查集,它无非包括三个操作:make_set(x).union_set(x ...

  5. CentOS6.5安装MySql5.5

    最近在CentOS上安装MySql,本来以为yum安装会很简单,但是却花了自己不少时间,所以决定和大家分享下. 首先,安装MySql源! 下载地址:http://dev.mysql.com/downl ...

  6. Wcf for wp8 调试Wcf服务程序(四)

    1.要以管理员身份进行登录vs2012 否则会提示: 2.在wcf 服务程序上设为启动项 3.编译 运行你的wcf服务程序 点击 就出现wcftestclient.exe 客户端调试程序 双击点击Re ...

  7. AngularJS 'Controller As'用法

    AngularJS 1.2版本中提供了Controller As语法,简单说就是可以在Controller中使用this来替代$scope,使得Controller更像一个传统的JS类,相对于$sco ...

  8. jmeter性能测试实战-web登录测试

    一.项目背景: 网站信息: 操作系统类型 二.需求: 登录并发测试 三.场景: 1s增加两个线程,运行2000次 分别看20.40.60并发下的表现 四.监控: 成功率.响应时间.标准差.cpu.me ...

  9. MAXIMO系统 java webservice 中PDA移动应用系统开发

    MAXIMO系统 java webservice 中PDA移动应用系统开发  平时经常用的wince PDA手持设备调用c#写的webservice, 当然PDA也可以调用java webservic ...

  10. jquery.validate.js的remote用法

    <script> $(function(){ $("#myform").validate( { rules: { name:{required:true,rangele ...