22. Generate Parentheses
写出n对括号的所有合法形式。
For example, given n = 3, a solution set is:
[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]
回溯求解,不过要单独统计左括号和右括号个数,同时加入左括号和加入右括号是平行的关系,不是if else,这样在回溯时才能加入右括号:
public List<String> generateParenthesis(int n) {
help(n, 0, new StringBuffer(""), 0, 0);
return res;
}
List<String> res = new ArrayList<>();
public void help(int n, int k, StringBuffer str, int open, int close) {
if (k == n*2) {
res.add(str.toString());
}
if (open < n) {
str.append('(');
help(n, k+1, str, open+1, close);
str.deleteCharAt(k);
}
//非if else
if (close < n && open > close) {
str.append(')');
help(n, k+1, str, open, close+1);
str.deleteCharAt(k);
}
}
301. Remove Invalid Parentheses
给一个不合法的包含括号的字符串,去掉最小的括号数量使其合法,有多少种合法的字符串形式。字符串中可能包含非括号字符,不用管它。
Input: “()())()”
Output: ["()()()", “(())()”]
还是有点难的,使用dfs:
- 遍历字符串,当遇到不合法的括号时,把从上个修改后的元素到这个元素之间的这一段子字符串再遍历一遍,是为了进行修改获得所有的正确子字符串,之后用这个正确子字符串加上后面的子字符串继续遍历
- 中间进行了return是为了处理了不合法的括号后直接跳出这个循环,不然结果就会带上这个不合法的括号
- 如果是左括号比右括号多的情况,把字符串反转,并且左右括号定义反转,这样就相当于转换成了右括号比左括号多了,重用了代码
public List<String> removeInvalidParentheses(String s) {
help(s, 0, 0, '(', ')');
return res;
}
List<String> res = new ArrayList<>();
public void help(String s, int kStart, int iStart, char leftPar, char rightPar) {
int open = 0, close = 0;
for (int k = kStart; k < s.length(); k++) {
if (s.charAt(k) == leftPar) open++;
if (s.charAt(k) == rightPar) close++;
if (open >= close) continue;
for (int i = iStart; i <= k; i++) {
if (s.charAt(i) == rightPar && (i == iStart || s.charAt(i-1) != rightPar))
help(s.substring(0, i) + s.substring(i+1, s.length()), k, i, leftPar, rightPar);
}
//这里返回是为了在去掉不合法括号后能跳过这次循环,如果不跳过下次循环就会带上不合法的括号
return;
}
String reverse = new StringBuffer(s).reverse().toString();
if (leftPar == '(')
help(reverse, 0, 0, rightPar, leftPar);
else
res.add(reverse);
}