[剑之オファー] 10フィボナッチシーケンス

一つ、問題

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それを調べる必要があります。計算はプロセス領域で理解する必要があります

おすすめ

転載: blog.csdn.net/qq_40996741/article/details/109233378