[剑之offer] 10 Fibonacci sequence

One, the problem

1. Write a function, enter n to find the nth term of the Fibonacci sequence. The definition of Fibonacci sequence is as follows

F(0) = 0, F(1) = 1

F(N) = F(N-1) + F(N-2), where N> 1.

The Fibonacci sequence starts with 0 and 1, and the subsequent Fibonacci numbers are obtained by adding the previous two numbers.

2. Example

Input: n = 2
Output: 1

Input: n = 5
Output: 5

2. Problem solving method

Problem solving idea:
The definition of Fibonacci sequence is f(n + 1) = f(n) + f(n-1)f(n+1)=f(n)+f(n−1), generating There are several ways to do item nn:

1. Recursion method:

Principle: Split the calculation of f(n)f(n) into two sub-problems f(n-1)f(n−1) and f(n-2)f(n−2), and recurse , With f(0)f(0) and f(1)f(1) as termination conditions.

Disadvantages: A large number of repeated recursive calculations, such as f(n)f(n) and f(n-1)f(n−1). Both downward recursion need to calculate f(n-2)f(n−2) separately Value.

2. Memory recursion method:

Principle: Based on the recursion method, create a new array of length nn to store the digital values ​​from f(0)f(0) to f(n)f(n) during recursion. If a number is repeatedly encountered Use directly from the array, avoiding repeated recursive calculations.

Disadvantages: Memory storage requires additional space of O(N)O(N).

3. Dynamic planning:

Principle: Take the Fibonacci sequence property f(n + 1) = f(n) + f(n-1)f(n+1)=f(n)+f(n−1) as the transfer equation.
From the perspective of computational efficiency and space complexity, dynamic programming is the best solution to this problem.

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;
    }


}

1000000007Need to look into it. Calculation needs to be understood in the process area

Guess you like

Origin blog.csdn.net/qq_40996741/article/details/109233378