头图

Topic description

Write a function, enter n to find the n item of the Fibonacci sequence (ie F(N) ). The Fibonacci sequence is defined as follows:

 F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

The Fibonacci sequence starts with 0 and 1, and the subsequent Fibonacci numbers are obtained by adding the previous two numbers.
Such as: fib(2) == 1 , fib(5) == 5

Likou original title address: https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/

solution

Scheme 1 Direct Recursion

The recursion calls itself, and executes continuously until it encounters a certain condition to stop the recursion

look for patterns

 第0项 == 0
第1项 == 1
第2项 == 第1项 + 第0项
第3项 == 第2项 + 第1项
第4项 == 第3项 + 第2项
......
第i项 == 第i-1项 + 第i-2项 // 从第2项开始,即 i >= 2

Use recursion to express rules

 function fib(i) {
    if (i == 0) {
        return 0
    }
    if (i == 1) {
        return 1
    }
    if (i >= 2) {
        /**
        * 这句话可以理解为:fib(i)函数执行的结果值等于return fib(i - 1) + fib(i - 2)
        * 即:fib(i) == fib(i - 1) + fib(i - 2)
        * 符合上方规律:第i项 == 第i-1项 + 第i-2项 // 从第2项开始,即 i >= 2
        */ 
        return fib(i - 1) + fib(i - 2) 
    }
}
console.time()
console.log('斐波那契第10项', fib(10)); // 55
console.timeEnd() // default: 0.279052734375 ms

We use timeEnd() to print out the approximate recursive execution time of the tenth item of fib(10) and find that it is 279 milliseconds. Here's an example of why it's a bit slow:

For example, if we want to execute fib(4) to find the value of the fourth item, it is not difficult to find that the second item and the first item are both calculated repeatedly, which wastes performance, so this method can be implemented, but due to repeated calculation The performance is not very good (so the recursive writing method is in force, it will not pass)

Next, let's see if we can reduce repeated calculations. The idea is: the data that has already been calculated will not be calculated and reused directly.

Option 2 uses object cache to retain calculation results for easy reuse

Ideas:

First define an object in advance to store the value of item 0 and item 1. In the subsequent calculation process, calculate the value of an item and store this value in the object; if you continue to calculate and find that the value of a certain item has been If it is stored in the object, it will be used directly. If it is not stored in the object, it will continue to be stored for subsequent use, so as to reduce repeated calculations and improve performance.

Code:

 let obj = {
    0: 0, // 第0项的值为0
    1: 1 // 第1项的值为1
}

function fib(i) {
    if (i == 0) {
        return obj[0]
    }
    if (i == 1) {
        return obj[1]
    }
    /**
     * 如果i不在obj中,即i不属于obj的key,比如i == 2
     * 就直接新增一份:obj[2] = obj[1] + obj[0]
     *       等式变换:obj[2] = fib(1) + fib(0)
     *       以此类推:obj[i] = fib(i - 1) + fib(i - 2) 
     *       这个表达式成立的条件是从i >= 2 开始,也就是i不在obj的key中
     *       所以如果不在的时候,就存一份使其在,那么后续需要再次计算的时候
     *       就直接复用即可
     * */
    // 这是从第2项开始的。若没有的,即之前没计算过的,就直接存一份在对象中,方便下次复用
    if (!(i in obj)) {
        obj[i] = fib(i - 1) + fib(i - 2)
        console.log('看看obj对象中存储的数据', obj);
        return fib(i - 1) + fib(i - 2)
    } else if (i in obj) { // 若是有的,即之前计算过的,就直接取到这个结果,直接用
        return obj[i]
    }
}

console.log('斐波那契', fib(6)); // 8

Screenshot of printing obj object:

An array can also be used here to make a cached data and store a calculated value, which will not be described here. The idea is the same, you can try it yourself

Option 3 defines that variables are accumulated to a certain item

Ideas:

Since the Fibonacci sequence is cumulative, we can just keep adding. When seeking: fib(6), we start adding from fib(1). Of course, we need to define a variable as a container for accumulation

Code:

 function fib(n) {
    let firstVal = 0 // 头一项为0
    let secondVal = 1 // 第二项为1
    let thirdVal = null // 第三项先定义一个null,预留着后续的累加
    if (n == 0) {
        return firstVal
    }
    if (n == 1) {
        return secondVal
    }
    if (n >= 2) {
        for (let i = 2; i <= n; i++) {
            thirdVal = secondVal + firstVal // 这一项等于前一项加上前前一项
            /** 相当于整体往前进一位 */
            firstVal = secondVal // 把前一项的值赋值给前前一项
            secondVal = thirdVal // 把这一项的值赋值给前一项
            console.log('看看累加的值', thirdVal);
        }
        return thirdVal
    }
}
console.log('斐波那契', fib(10)); // 55

Print the accumulated value:

Summarize

A good memory is not as good as a bad writing, so record it ^_^ , although it was recorded in the front, and forgotten in the back...

There are many ways to solve the Fibonacci sequence, for example, you can also use general term formula expressions and the like. The main idea is that in our daily work, for some data verification and data architecture processing, we often need to use a little algorithmic thinking in it, so that the code written in this way is elegant (install X)

水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负