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. percona-xtrabackup备份mysql

    title: 1.percona-xtrabackup备份mysql date: 2016-04-10 23:19:12 tags: mysql categories: mysql --- 一.per ...

  2. 封装自己的ajax函数

    url为具体的url地址, onsuccess为正常返回时的结果, onfail为错误返回时的结果 function MyAjax(url,onsuccess,onfail) { var xhr = ...

  3. mysql_3

    日期查询: mysql> select * from member where birthday > '1962-01-01';

  4. php 练习

    下拉样式 <select> <?php $a = array( array("n001 汉族"), array("n002 回族"), arr ...

  5. 安装memcached服务器和PHP中添加memcache拓展模块

    Memcached是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提拱动态 数据驱动网站的速度. memcached ...

  6. 转载——用Mixer API函数调节控制面板的音频设置

    关键词:Mixer函数,控制面板,音频设备调节 如果你用过windows的音频设备,比如播放音乐或者录音,聊天,调节麦克或者声音的大小,以及设置静音,都可以通过控制面板中的音频设置面板来调节,你对于下 ...

  7. mac 下修改Hosts文件

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

  8. hdu 4091 线性规划

    分析转自:http://blog.csdn.net/dongdongzhang_/article/details/7955136 题意 :  背包能装体积为N,  有两种宝石, 数量无限, 不能切割. ...

  9. HTML <img> 标签的 height 和 width 属性

    定义和用法 <img> 标签的 height 和 width 属性设置图像的尺寸. 提示:为图像指定 height 和 width 属性是一个好习惯.如果设置了这些属性,就可以在页面加载时 ...

  10. Excel文件导入SQL Server数据库表

    --office 2003--如果接受数据导入的表已经存在insert into DemoTable select * from OPENROWSET('MICROSOFT.JET.OLEDB.4.0 ...