所以我有这个问题。我试图编写一个程序来打印所有有效的括号排列,即3个括号,我们可以有((())),(()()),()()(),(())()等
我有一个工作代码
public static void main(String[] args) {
int number = 3; // No. of brackets
int cn = number;
int on = number;
// open and closed brackets respectively
char[] sol = new char[6];
printSol(on, cn, sol, 0);
}
public static void printSol(int cn, int on, char[] sol, int k) {
if (on == 0 && cn == 0) {
System.out.println("");
for (int i = 0; i < 6; i++) {
System.out.print(sol[i]);
}
}
else {
if (on > 0) {
if (cn > 0) {
sol[k] = '(';
printSol(on - 1, cn, sol, k + 1);
}
}
if (cn > on) {
sol[k] = ')';
printSol(on, cn - 1, sol, k + 1);
}
}
}
现在的问题是我想使用ArrayList而不是使用char数组。 我试过但是我遇到了错误。如果有人有任何建议,请告诉我。提出这个问题的主要目的是我想知道在递归问题中我何时更喜欢ArrayLists而不是数组。
P.S。 我很抱歉由于冲浪限制我不得不键入整个程序,并且也可能是一些语法错误,但我尽力了。 谢谢 莫希特
答案 0 :(得分:2)
我认为你使用char[]
做得很好。这很快就达到了目的。
我会说你在实践中遇到的大多数递归问题都不遵循这种模式。这是因为通常需要递归的问题,您在搜索树上搜索一个特定的目标(树上的一个特定叶节点)。您正在执行迭代:您正在尝试访问树上的每个叶节点,并为每个叶节点执行操作。
使用常见的搜索算法(如深度优先搜索),您无需在递归时准备结果,而是在找到目标后放松。
但是对于你这样做的情况,char[]
效果很好。您基本上是通过参数sol
和k
模拟堆栈(sol保存数据,而k指向堆栈顶部)。正如其他人注意到的那样,您可以直接使用堆栈(通过传递Deque<Character>
实现,通常是LinkedList
)。
在我看来ArrayList
是向后退一步。如果您要使用集合,请使用针对该问题的集合。
编辑:以下是使用Deque的未经测试的实现:
public static void printSol(int cn, int on, Deque<Character> sol) {
if (on == 0 && cn == 0) {
System.out.println("");
for ( Iterator<Character> it = sol.descendingIterator(); it.hasNext(); ) {
System.out.println(it.next());
}
}
else {
if (on > 0) {
if (cn > 0) {
sol.push('(');
printSol(on - 1, cn, sol);
sol.pop();
}
}
if (cn > on) {
sol.push(')');
printSol(on, cn - 1, sol);
sol.pop();
}
}
}
//...
printSol(3, 3, new ArrayDeque<Character>(6));
正如您所看到的,很少有变化。
编辑2:我们根本没有讨论过这个具体问题的一件事是StringBuilder
。
StringBuilder是一种可变的String类型,允许您轻松追加和删除字符。对于这个问题,这也是一个很好的解决方案:
public static void printSol(int cn, int on, StringBuilder sol) {
if (on == 0 && cn == 0) {
System.out.println(sol);
}
else {
if (on > 0) {
if (cn > 0) {
sol.append('(');
printSol(on - 1, cn, sol);
sol.deleteCharAt(sol.length()-1);
}
}
if (cn > on) {
sol.append(')');
printSol(on, cn - 1, sol);
sol.deleteCharAt(sol.length()-1);
}
}
}
答案 1 :(得分:1)
您希望避免在递归时按值传递大型数据结构,因为它会占用大量内存。总的来说,这是我唯一能想到的。传递对数组或ArrayList的引用是可以的。我更喜欢ArrayList。
特别针对此问题查看Java的Stack
类。
答案 2 :(得分:0)
我意识到没有人(包括我自己)真的回答了你的问题。我认为你已经确信使用ArrayList
在这里是不可取的。但是你怎么能让它发挥作用呢?
最简单的方法是基本上用它伪造一个堆栈:
public static void printSol(int cn, int on, ArrayList<Character> sol) {
//...
sol.add('(');
printSol(on - 1, cn, sol);
sol.remove(sol.size() - 1);