n ペアの括弧のすべての有効な組み合わせを出力するアルゴリズムを実装するために、古典的な問題を実行しようとしました。
このプログラムを見つけました(完全に機能します):
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/そのすべて-カタロニア語/ )
あなたの意見では、時間の複雑さはどのくらいですか? ここで主定理を適用できるかどうか。