我必须编写一个程序,它返回括号括起来的所有不同方法。例如,如果给定的字符串是“abcd”,那么我们将得到这五个不同的结果:
((ab)c)d (a(bc))d (ab)(cd) a((bc)d) a(b(cd))
括号的数量当然取决于字符串的长度,但我认为字符串-2的长度是合适的(我们不知道我们可以使用的括号数... )。这似乎很简单:我只需将括号插入每个可能的位置。我认为递归适用于此。
我试着写这个:
private static ArrayList<String> generateParens(String string, ArrayList<String> list, int leftRem, int rightRem, char[] str, int count) {
if (leftRem < 0 || rightRem < leftRem) return null;
if (leftRem == 0 && rightRem == 0) { /* all out of left and right parentheses */
String s = String.copyValueOf(str);
list.add(s);
} else {
if (leftRem > 0) { // try a left paren, if there are some available
str[count] = '(';
str[count+1] = string.charAt(count);
generateParens(string, list, leftRem - 1, rightRem, str, count+1);
}
if (rightRem > leftRem) { // try a right paren, if there’s a matching left
str[count] = string.charAt(count);
str[count+1] = ')';
generateParens(string, list, leftRem, rightRem - 1, str, count + 1);
}
}
return list;
}
public static ArrayList<String> generateParens(String string) {
char[] str = new char[string.length()*2]; //because we have a PAIR of parenthese
ArrayList<String> list = new ArrayList<String>();
String str2 = string + string;
return generateParens(str2, list, string.length()-2, string.length()-2, str, 0);
}
我试着写一个递归函数,但我的递归效果不是很好,所以我遇到了很多问题,尤其是索引问题。我尝试了很多东西,但我仍然有问题;我不确定这是否仅仅是由于索引。)
你可以帮我解决一下吗?
答案 0 :(得分:1)
您认为这是一个字符插入问题。我建议另一种观点。
将此视为代数表达式,可能是 a + b / c - d ,但没有运算符优先级规则。 你必须找到所有可能的不同方法来计算:哪些操作分别是第一,第二和第三。查看它的另一种方法是,您必须构建具有四个叶节点的所有可能的二叉树。这给了我们表达式
((a+b)/c)-d (a+(b/c))-d (a+b)/(c-d) a+((b/c)-d) a+(b/(c-d))
我现在坚持使用代数的想法。你是正确的,你需要在任何完整的解决方案中准确地使用N-2对括号。你有N-1个操作,除了最后一个(最外面的操作符)之外的所有操作都需要一对括号。
我建议你从树的底部开始,然后继续前进。保留您必须加入的字符串列表。在每次迭代中,选择一对字符串进行连接;在它们周围加上括号,并用较短的列表重复。当列表只有两个项目时,您可以在没有最外面的括号的情况下连接它们。例如,在获取第二个字符串时,您的序列将使用括号(数组表示法?)作为列表:
private static genParen(leaves) // is the protocol. Now for the execution sequence ...
call genParen(["a", "b", "c", "d"])
// Pick the second join ...
// Concatenate the 2nd & 3rd items; add parentheses
leaves[1] = "(" + leaves[1] + leaves[2] + ")"
// Delete item 2 from leaves, and recur:
call genParen(["a", "(bc)", "d"])
// This time, pick the first join ...
leaves[0] = "(" + leaves[0] + leaves[1] + ")"
// Delete item 1 from leaves, and recur:
call genParen(["(a(bc))", "d"])
// There are now only 2 elements remaining, so ...
return leaves[0] + leaves[1]
现在,当您向上走回树时,您可以将每个解决方案添加到您维护的解决方案列表中。
“先选择”或“选择第二”连接逻辑不是挥手:你的函数必须依次遍历每个可能的选择:对于N个元素的列表,你有N-1个可能的选择。您必须使用较短的列表进行重复,并保存结果。
此外,您必须查看结果列表,因为有方法可以复制输出字符串。例如,有两种方法可以生成(ab)(cd),具体取决于您首先选择的单字母叶对。
这足以让你走向解决方案吗?