繁体   English   中英

如何确定包含优化的递归算法的大 O?

[英]How do I determine the Big O of a recursive algorithm that includes an optimization?

我知道斐波那契算法的常规递归函数是 O(2^n),因为它在每次后续调用中调用自己两次,使其成本加倍。 但是,在添加了我所看到的优化(序列解决方案的哈希表)之后,您如何确定它降低了多少复杂性(如果有的话)?

例如:

import java.util.*;

public class Solution {

    static Hashtable<Integer, Integer> numbers = new Hashtable<Integer, Integer>();

    public static int fibonacci(int n) {
        if(n == 0 || n == 1){
            return n;
        }else if(numbers.containsKey(n)){
            return numbers.get(n);
        }else {
            int result = fibonacci(n-1) + fibonacci(n-2);
            numbers.put(n, result);
            return result;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.close();
        System.out.println(fibonacci(n));
    }
}

你的算法是 O(n)。 你实现的是所谓的记忆。 这真正意味着当将问题分解为两个(或更多)部分重叠的子问题时(例如F(5) = F(4) + F(3) ),两者都需要计算 F(2) 所以它们重叠)当一个值被计算出来时,它会被存储起来,所以下次需要时它已经被计算出来了。

这意味着为了计算F(n)你将递归计算所有F(i) ,i<n并且如果一些F(i)需要不止一次,它将只计算一次并且可以在O(1) (由于 o 哈希表)。所以总体上将是O(n)

这与动态算法版本非常相似(有一点不同,即不是构建解决方案,例如 F(0),F(1),F(2) ...F(n) 而是向后进行跟踪你已经计算(记忆))。 虽然我没有检查你的记忆算法是否有任何错误......只是解释记忆算法的概念和复杂性。

正如评论中指出的,这个函数的复杂度是 Theta(2^n):

Fibonacci(n) {
    if (n < 0) return 0;
    if (n < 2) return 1;
    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

我们可以用归纳法证明这一点。 基本情况:对于n = 0n = 10.5 * 2^n <= Fibonacci(n) = 1 <= 2 * 2^n 归纳假设:假设这适用于n直到并包括k 归纳步骤:证明0.5 * 2^(k+1) <= Fibonacci(k+1) <= 2 * 2^(k+1) 代入,我们得到0.5 * 2^(k+1) = 2*2^(k-1) <= 2*Fibonacci(k-1) <= Fibonacci(k) + Fibonacci(k-1) <= 2*Fibonacci(k) <= 2 * 2^k <= 2 * 2^(k+1) 至此,证明完毕。

解决方案的哈希表(有时称为memo ,因此memoization )防止每个k多次调用Fibonacci(k) 由于Fibonacci(n)仅依赖于Fibonacci(0) , Fibonacci(1) , ..., Fibonacci(n-1) ,并且由于哈希表和检查阻止了这些中的任何一个被多次调用,每个都被精确地调用一次,并且由于每个都为任何给定的n执行恒定量的工作,因此总工作量是O(n) 现在很难考虑递归关系(我们有副作用并且需要条件),所以我必须利用这种“技巧”论证。 不幸的是,大多数证明都需要某种“技巧”,归纳法是一个例外。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM