C#でトップダウン方式(メモ化)を用いてフィボナッチ数列を実装する方法
フィボナッチ数列は、0または1から始まり、その後に1が続き、以降の各数値(フィボナッチ数と呼ばれます)が「直前の2つの数値の合計」というルールに従って生成される数列です。
本記事で解説するトップダウン方式は、大きな問題をより小さく理解しやすい単位へ分割して解決していく手法です。フィボナッチ数列の計算においては、再帰呼び出しの結果を配列(メモ化テーブル)にキャッシュすることで、同じ計算を繰り返す無駄を省き、効率的に処理できます。
計算量について
- 時間計算量: O(N) — 各フィボナッチ数は一度だけ計算され、以降はメモ化された結果を参照するためです。
- 空間計算量: O(N) — 数値のサイズと同等の追加配列(メモ化用の配列)を作成するためです。
実装例
public class DynamicProgramming{
public int fibonacciTopdownApproach(int n,int[] dpArr ){
if(n==0 || n == 1){
return n;
}
if(dpArr[n] != 0){
return dpArr[n];
}
int res = fibonacciTopdownApproach(n - 1,dpArr) + fibonacciTopdownApproach(n - 2,dpArr);
return dpArr[n] = res ;
}
}
static void Main(string[] args){
DynamicProgramming dp = new DynamicProgramming();
int[] dpArr = new int[150];
Console.WriteLine(dp.fibonacciTopdownApproach(12, dpArr));
}コードのポイント
- ベースケースとして、nが0または1の場合はそのままnを返します。
- 配列
dpArr[n]にすでに計算結果が格納されている場合(0以外の場合)は、再帰せずにその値を返します。これが「メモ化」による高速化の仕組みです。 - それ以外の場合は、n-1とn-2に対して再帰的に関数を呼び出し、その合計を配列に保存したうえで返します。
実行結果
144
このプログラムでは、12番目のフィボナッチ数である144が出力されます。素朴な再帰実装では指数時間O(2^N)かかるところを、トップダウン方式(メモ化)を採用することで線形時間O(N)まで大幅に改善できる点が、動的計画法の大きな利点です。
-
Java 9でJavaFXを使ってJShellをプログラムから実装する方法
JShellは、サンプル式を対話的に実行できるツールです。通常はコマンドラインから利用しますが、JavaFXアプリケーションの中でプログラム的にJShellを実装することも可能です。その場合、Javaプログラムに以下のパッケージをインポートする必要があります。import jdk.jshell.JShell; import jdk.jshell.SnippetEvent; import jdk.jshell.VarSnippet;これらのクラスの役割は次のとおりです。JShell:評価エンジンの本体。式や文を評価(eval)するためのAPIを提供します。SnippetEvent:評価結果として
-
Javaでスタックを使ってキュー(Queue)を実装する方法を解説
キューとスタックの基本Queue(キュー)は Collection インターフェースを継承したクラスで、FIFO(First-In-First-Out:先入れ先出し)方式による要素の挿入と削除をサポートします。一方、Stack(スタック)は Vector クラスのサブクラスであり、LIFO(Last-In-First-Out:後入れ先出し)方式でオブジェクトを管理します。つまり、スタックの一番上に追加された最後の要素が、最初に取り出される要素になります。この2つのデータ構造の性質は正反対ですが、スタックを2つ組み合わせることで、キューを実装することが可能です。以下では、その具体的な実装方法を紹