追根揭底-循环\迭代\分治详细使用

简介: 追根揭底-循环\迭代\分治详细使用

Multiple solutions of Fibonacci(Python or Java)


Violence law(Top-down)


It can be solved directly according to the known conditions


(f (0) = 0, f (1) = 1 F(N) = F(N - 1) + F(N - 2), for N > 1)


Python Code

class Solution:
    def fib(self, N: int) -> int:
        if N == 1 or N == 2: return N
        return self.fib(N - 1) + self.fib(N - 2)


Java Code


class Solution {    public int fib(int N) {        if (N == 1 || N == 2) return 1;        return fib(N - 1) + fib(N - 2);
    }
}class Solution {    public int fib(int N) {        return N < 2 ? N : fib(N - 1) + fib(N - 2);
    }
}


Violence law add cache(Pruning)


We know that if we don’t do any processing, we will repeat too many

calculations, which is very bad


The processing idea will avoid repeated calculation


Python Code

class Solution2:
    @functools.lru_cache()
    def fib(self, N: int) -> int:
        if N <= 1: return N
        else: return self.fib(N - 1) + self.fib(N - 2)


Java Code


class Solution {    private Integer[] cache = new Integer[31];    public int fib(int N) {        if (N <= 1) return N;
        cache[0] = 0;
        cache[1] = 1;        return memoize(N);
    }    public int memoize(int N) {      if (cache[N] != null) return cache[N];
      cache[N] = memoize(N-1) + memoize(N-2);      return memoize(N);
    }
}


Divide and conquer solution


Recursion, iteration, divide and conquer, backtracking, they do not have a clear distinction


Recursion:The core idea is to govern separately and unify the officials


class Solution:
    def fib(self, N: int) -> int:
        memo = {}        if N < 2: return N        if N-1 not in memo: memo[N-1] = self.fib(N-1)        if N-2 not in memo: memo[N-2] = self.fib(N-2)        return memo[N-1] + memo[N-2]


Dynamic recursion(Bottom up)


Basic solutions


More initial value, continuous dynamic recursive


Python Code


class Solution:
    def fib(self, N: int) -> int:
        if N < 2: return N
        dp = [0 for _ in range(N + 1)]
        dp[0], dp[1] = 0, 1
        for i in range(2, N + 1):
            dp[i] = dp[i - 1] + dp[i - 2]        return dp[- 1]class Solution:
    def fib(self, N: int) -> int:
        if N == 0: return 0
        memo = [0,1]        for _ in range(2,N+1):
            memo = [memo[-1], memo[-1] + memo[-2]]        return memo[-1]


Java Code


class Solution {
    public int fib(int N) {
        if (N <= 1) return N;
        if (N == 2) return 1;
        int curr = 0, prev1 = 1, prev2 = 1;
        for (int i = 3; i <= N; i++) {
            curr = prev1 + prev2;
            prev2 = prev1;
            prev1 = curr;
        }
        return curr;
    }
}


Use better base types (tuples) to improve performance


class Solution:
    def fib(self, N: int) -> int:
        if N == 0: return 0
        memo = (0,1)        for _ in range(2,N+1):
            memo = (memo[-1], memo[-1] + memo[-2])        return memo[-1]


Better solutions


Python Code


class Solution:
    def fib(self, N: int) -> int:
        curr, prev1, prev2 = 0, 1, 1
        for i in range(3, N + 1):
            curr = prev1 + prev2
            prev2 = prev1
            prev1 = curr        return currclass Solution5:
    def fib(self, N: int) -> int:
        prev, now = 0, 1
        for i in range(N):
            prev, now = now, now + prev        return prev


Java Code


class Solution {    public int fib(int N) {    if (N == 0) return 0;    if (N == 2 || N == 1) return 1;    int prev = 1, curr = 1;    for (int i = 3; i <= N; i++) {        int sum = prev + curr;
        prev = curr;
        curr = sum;
    }    return curr;
    }
}


Mathematical conclusion method


Python Code


class Solution:
    def fib(self, N: int) -> int:
        sqrt5 = 5 ** 0.5
        fun = pow((1 + sqrt5) / 2, n + 1) - pow((1 - sqrt5) / 2, n + 1)        return int(fun / sqrt5)


Java Code


class Solution {    public int fib(int N) {        double sqrt5 = (1 + Math.sqrt(5)) / 2;        return (int)Math.round(Math.pow(sqrt5, N)/ Math.sqrt(5));
    }
}


目录
相关文章
|
3月前
|
算法
尾递归和迭代的区别是什么?
【10月更文挑战第24天】尾递归和迭代各有优缺点,在实际编程中需要根据具体情况选择合适的方法。在一些情况下,尾递归可以提供更简洁高效的实现方式;而在另一些情况下,迭代可能是更为可靠的选择。
|
4月前
|
存储
使用迭代代替递归
使用迭代代替递归
|
4月前
|
算法
递归和迭代详解
递归和迭代详解
|
算法
用递归的思想实现二叉树前、中、后序迭代遍历
用递归的思想实现二叉树前、中、后序迭代遍历
96 1
|
9月前
|
算法
递归算法和迭代算法有什么不同
递归算法和迭代算法有什么不同
85 1
二叉树的遍历(递归And迭代)
二叉树的遍历(递归And迭代)
58 0
|
9月前
|
算法
每日一题——排序链表(递归 + 迭代)
每日一题——排序链表(递归 + 迭代)
|
缓存 算法 Java
使用迭代优化递归程序
大家好,我是王有志。 今天我们将会分析上篇文章中递归算法存在的问题,并通过迭代去优化。
127 1
使用迭代优化递归程序
|
算法
斐波那契数列(递归+迭代)
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、3
155 0