我尝试解决一个经典问题,即实现一个算法来打印n对括号的所有有效组合。
我找到了这个程序(它完美地工作):
据我理解,这个想法是尽可能添加左括号。对于右括号,只有在剩余的右括号数量大于左括号时才添加。如果我们已经使用了所有的左右括号,我们将把新的组合添加到结果中。我们可以确定不会有任何重复的构造字符串。
对于我来说,这种递归就像我们处理树时所做的事情,例如进行前序遍历:每当可能时,我们都会进入左节点,如果不行,我们就向右走,然后我们尝试在此步骤之后立即向左走。如果我们不能,我们就“回来”并向右走,然后重复遍历。在我看来,这里的想法完全相同。
因此,天真地,我认为时间复杂度将是类似于O(log(n))、O(n.log(n))或者带有对数的东西。但是,当我试图搜索相关内容时,我发现了一些叫做“卡特兰数”的东西,我们可以用它来计算括号的组合数量...(https://anonymouscoders.wordpress.com/2015/07/20/its-all-about-catalan/)
我找到了这个程序(它完美地工作):
public static void addParen(ArrayList<String> list, int leftRem, int rightRem, char[] str, int count) {
if (leftRem < 0 || rightRem < leftRem) return; // invalid state
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] = '(';
addParen(list, leftRem - 1, rightRem, str, count + 1);
}
if (rightRem > leftRem) { // try a right paren, if there’s a matching left
str[count] = ')';
addParen(list, leftRem, rightRem - 1, str, count + 1);
}
}
}
public static ArrayList<String> generateParens(int count) {
char[] str = new char[count*2];
ArrayList<String> list = new ArrayList<String>();
addParen(list, count, count, str, 0);
return list;
}
据我理解,这个想法是尽可能添加左括号。对于右括号,只有在剩余的右括号数量大于左括号时才添加。如果我们已经使用了所有的左右括号,我们将把新的组合添加到结果中。我们可以确定不会有任何重复的构造字符串。
对于我来说,这种递归就像我们处理树时所做的事情,例如进行前序遍历:每当可能时,我们都会进入左节点,如果不行,我们就向右走,然后我们尝试在此步骤之后立即向左走。如果我们不能,我们就“回来”并向右走,然后重复遍历。在我看来,这里的想法完全相同。
因此,天真地,我认为时间复杂度将是类似于O(log(n))、O(n.log(n))或者带有对数的东西。但是,当我试图搜索相关内容时,我发现了一些叫做“卡特兰数”的东西,我们可以用它来计算括号的组合数量...(https://anonymouscoders.wordpress.com/2015/07/20/its-all-about-catalan/)
你认为时间复杂度是什么?我们能否在这里应用主定理?