一つ、問題
1.関数を記述し、nを入力して、Fibonacciシーケンスのn番目の項を検索します。フィボナッチシーケンスの定義は次のとおりです。
F(0)= 0、F(1)= 1
F(N)= F(N-1)+ F(N-2)、ここでN> 1。
フィボナッチシーケンスは0と1で始まり、後続のフィボナッチ番号は前の2つの番号を加算することによって取得されます。
2.例
入力:n = 2
出力:1
入力:n = 5
出力:5
2.問題解決方法
問題解決のアイデア:
Fibonacciシーケンスの定義はf(n + 1)= f(n)+ f(n-1)f(n + 1)= f(n)+ f(n-1)であり、アイテムnnを実行する方法はいくつかあります。
1.再帰方法:
原則:f(n)f(n)の計算を2つのサブ問題f(n-1)f(n-1)とf(n-2)f(n-2)に分割し、再帰する、終了条件としてf(0)f(0)およびf(1)f(1)を使用。
短所:f(n)f(n)やf(n-1)f(n-1)など、多数の再帰計算が繰り返されます。両方の下方再帰では、f(n-2)f(n-2)を個別に計算する必要があります。値。
2.メモリ再帰方法:
原則:再帰法に基づいて、再帰中にf(0)f(0)からf(n)f(n)までのデジタル値を格納するために長さnnの新しい配列を作成します。繰り返しの再帰計算を避けて、アレイから直接使用します。
短所:メモリストレージには、O(N)O(N)の追加スペースが必要です。
3.動的計画:
原理:伝達方程式として、フィボナッチシーケンスプロパティf(n + 1)= f(n)+ f(n-1)f(n + 1)= f(n)+ f(n-1)を取ります。
計算効率とスペースの複雑さの観点から、動的プログラミングはこの問題の最良の解決策です。
package com.haoxiansheng.demo01.SwordfingerOffer;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* @author flame
* @data 2020/10/22
*/
@Slf4j
public class FibDemo {
public static void main(String[] args) {
log.info("fib=>{}", fib(2000));
}
// 为什么选1000000007
//理由大概是“int32类型是十位数,对1e9取模可防止int32溢出”、“1e9+7是质数,
//对质数取模可以尽可能地让模数避免相等”以及“1e9+7是离1e9最近的质数,比较好记”
public static int fib(int n) {
int a =0;
int b = 1;
int sum;
for (int i =0 ; i< n; i++) {
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;
}
int constant = 1000000007;
public int fib1(int n) {
if (n < 2)
return n;
int first = fib(n - 1) % constant;
int second = fib(n - 2) % constant;
return (first + second) % constant;
}
public int fib2(int n) {
return fib(n, new HashMap<>());
}
public int fib(int n, Map<Integer, Integer> map) {
if (n < 2)
return n;
if (map.containsKey(n))
return map.get(n);
int first = fib(n - 1, map) % constant;
map.put(n - 1, first);
int second = fib(n - 2, map) % constant;
map.put(n - 2, second);
int res = (first + second) % constant;
map.put(n, res);
return res;
}
// 非递归解决
public int fib3(int n) {
int constant = 1000000007;
int first = 0;
int second = 1;
while (n-- > 0) {
int temp = first + second;
first = second % constant;
second = temp % constant;
}
return first;
}
}
1000000007それを調べる必要があります。計算はプロセス領域で理解する必要があります