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

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

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月前
6.2二叉树的迭代遍历
6.2二叉树的迭代遍历
34 1
|
2月前
|
算法
尾递归和迭代的区别是什么?
【10月更文挑战第24天】尾递归和迭代各有优缺点,在实际编程中需要根据具体情况选择合适的方法。在一些情况下,尾递归可以提供更简洁高效的实现方式;而在另一些情况下,迭代可能是更为可靠的选择。
|
3月前
|
存储
使用迭代代替递归
使用迭代代替递归
|
3月前
|
算法
递归和迭代详解
递归和迭代详解
02_二叉树的迭代遍历
02_二叉树的迭代遍历
|
7月前
|
算法
数据结构和算法学习记录——时间复杂度的计算(嵌套循环、大O的渐进表示法、双重循环、常数循环、strchr、冒泡排序、二分查找、斐波那契数列递归)
数据结构和算法学习记录——时间复杂度的计算(嵌套循环、大O的渐进表示法、双重循环、常数循环、strchr、冒泡排序、二分查找、斐波那契数列递归)
526 1
|
8月前
|
算法
递归算法和迭代算法有什么不同
递归算法和迭代算法有什么不同
79 1
二叉树的遍历(递归And迭代)
二叉树的遍历(递归And迭代)
54 0
|
8月前
|
测试技术
循环复杂度
循环复杂度
49 0
|
算法
斐波那契数列(递归+迭代)
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、3
145 0