题目
分析
首先明确一个问题:如何判断一个括号序列是不是合法的序列?
方法就是遍历这个序列,同时初始化一个x = 0,如果遇到左括号x就加一,遇到右括号就减一,如果遍历过程中x小于0,那么这个序列一定不是合法的序列;遍历完成后如果x等于0就是合法序列,否则是不合法的序列。代码如下:
//检验序列是否是合法的括号序列,current是序列值
public boolean valid(char[] current) {
int balance = 0;
for (char c: current) {
if (c == '(') {
++balance;
} else {
--balance;
}
if (balance < 0) {
return false;
}
}
return balance == 0;
}
第一种方式:生成所有的序列,判断其中合法的序列
class Solution {
public List<String> generateParenthesis(int n) {
List<String> combinations = new ArrayList<String>();
generateAll(new char[2 * n], 0, combinations);
return combinations;
}
public void generateAll(char[] current, int pos, List<String> result) {
if (pos == current.length) {
if (valid(current)) {
result.add(new String(current));
}
} else {
current[pos] = '(';
generateAll(current, pos + 1, result);
current[pos] = ')';
generateAll(current, pos + 1, result);
}
}
public boolean valid(char[] current) {
int balance = 0;
for (char c: current) {
if (c == '(') {
++balance;
} else {
--balance;
}
if (balance < 0) {
return false;
}
}
return balance == 0;
}
}
第二种方式:对第一种方式进行了优化,我们知道左括号的最大数量就是n,而右括号的添加必须小于等于左括号的数量,因此可以对这些不合法的序列进行剔除。
public class Solution {
public ArrayList<String> generateParenthesis (int n) {
// write code here
ArrayList<String> res = new ArrayList();
StringBuffer buffer = new StringBuffer();
generate(buffer,0,0,n,res);
return res;
}
/*参数说明:
1. buffer:保存中间生成的括号序列
2. left:左括号的数量
3. right:右括号的数量
4. max;合法序列左右括号的最大数量
5. res:保存所有的合法括号序列
*/
public void generate(StringBuffer buffer,int left,int right,int max,ArrayList<String> res) {
if(buffer.length() == max * 2) {
res.add(buffer.toString());
return;
}
if(left < max) {//如果左括号的数量小于最大数量
buffer.append('(');
generate(buffer,left + 1,right,max,res);
buffer.deleteCharAt(buffer.length() - 1);
}
if(right < left) {//如果右括号的数量小于左括号的数量
buffer.append(')');
generate(buffer,left,right + 1,max,res);
buffer.deleteCharAt(buffer.length() - 1);
}
}
}