読者です 読者をやめる 読者になる 読者になる

CodeIQ 参加記録

  • CodeIQというサイトで問題に挑戦した記録です。
  • 気が向いたら不定期に更新します。

第72回「今週のアルゴリズム:左右対称の二分探索木」

アルゴリズム
1~nまでのn個の節点を持つ二分探索木においてnが偶数の時は
左右対称のものはできないので、奇数のものについてだけ考える。
二分探索木はある節点の左側は全てその節点より小さい数、
右側はその節点より全て大きい数になるので、左右対称になるのは
1〜nのちょうど真ん中の数を根とした二分木の片側の部分木のパターンの 総数を数えれば良い。

1〜mまでのm個の要素数の二分探索木の総数を考える。
m=1の時、二分探索木は1個
m=2の時、二分探索木は2個
m=3の時、3を根とするm=2のパターン2個とその対称形の
1を根とする2個プラス2を根とする1個の合計5個
m=4の時、4を根とするm=3のパターンとそれの対称形の合計10個
プラス、2を根とする2の左1x右2の2パターン、3を根とする左2x右1の
2パターンの全ての合計14個となる。
ここから漸化式を求めて・・・となるが、
実はこれは カタラン数 として知られており、漸化式は次の通りである。

{ C_0 =1,\quad C_{n+1}=\frac{2(2n+1)}{n+2} }

これを用いてRubyで解答した。(81byte)

gets;m=(n=$_.to_i)%2==0?0:n/2;c=1;(1...m).each{|i|c=2*(2*i+1)*c/(i+2)};p m==0?m:c

正解でした。