【问题标题】:generating function: faster generation of F(n)生成函数:更快地生成 F(n)
【发布时间】:2012-07-09 04:39:47
【问题描述】:

我最近做了一个测试......这个问题很长,解决方案归结为 F(n) = 2*F(n-1) + 2*F(n-2)...

我有一个使用动态规划的 O(n) 解决方案......但是,考官并不满意......

我的解决方案是在计算时将每个 F(n) 简单地存储在一个数组中。花了 O(n) 时间。 由于我们只需要前两个元素,因此只需使用两个变量,就可以解决空间问题。

但是 O(n) 不够快...

该函数看起来像斐波那契函数,并且可以在 O(lg n) 时间内生成一个斐波那契数......但我无法为我的问题得到一个 O(lg n) 求解......

所以我的问题是如何提高函数的时间复杂度?

【问题讨论】:

标签: algorithm


【解决方案1】:

完全一样。在matrix form中表达您的复发;这将问题简化为求矩阵的 n 次方,which can be done in log(n) time

【讨论】:

    【解决方案2】:

    对于任何线性递推关系(就是这样),都有一个封闭公式。

    它涉及求解特征多项式,在这种情况下是:

    t^2 - 2*t - 2 = 0   (since F(n) - 2 * F(n-1) - 2 * F(n-2) = 0)
    

    如果t1和t2是这个二次方程的(复)解,那么公式是:

    F(n) = a * t1^n + b * t2^n
    

    其中 a 和 b 是常数,可以从初始条件(即本例中的 F(0) 和 F(1) 的值)中找到。 IE。

    F(0) = a + b
    F(1) = a * t1 + b * t2
    

    求解 a 和 b:

    a = ( t2 * F(0) - F(1) ) / ( t2 - t1 )
    b = ( t1 * F(0) - F(1) ) / ( t1 - t2 )
    

    在这种特殊情况下,特征多项式的根是:

    t1 = 1 + sqrt(3)
    t2 = 1 - sqrt(3)
    

    【讨论】:

    • +1 尽可能使用数学。 (另外:很好的背景和解释,为读者提供了如何在可能的情况下开发这些方程的工具)
    • 一个重要的提示:封闭形式的解决方案并不意味着快速 O(1) 或 O(lg n) 解决方案。 t1t2 计算第 n 项所需的精度随着 n 而增长。
    • @tskuzzy:如果你很狡猾,就不会。 (a + b.sqrt(3)) * (c + d.sqrt(3)) == (e + f.sqrt(3)),其中e == (a.c + b.d)f == (a.d + b.c)。换句话说,这一切都可以用整数数学来完成。
    • @OliCharlesworth:等等,我没有遵循。这些方程式是从哪里来的,它们的含义是什么?
    • @tskuzzy:您的原始评论暗示由于精度限制, sqrt(3) 的非理性/分数性质将是一个问题。我的评论指出这不是问题。我给出的方程式只是一个例子;他们说明了在 sqrt(3) 上只用整数算术处理代数是可能的。
    【解决方案3】:

    在您的解决方案中,您还使用了 O(n) 内存。

    您可以使用简单的循环来计算第 n 个斐波那契元素:

    您唯一需要保存的是最后 3 个 (a1,a2,a3) 元素,在每次迭代中,您将 a1 更新为 a2,将 a2 更新为 a3,并将 a3 更新为 old(a1) + old (a2)(您可以为此使用 2 个临时变量)。

    所以我们得到了运行时 O(n) 只有 O(1) 内存的简单算法。

    【讨论】:

    • OP 要求提高时间复杂度,而不是空间复杂度...
    猜你喜欢
    • 2016-05-12
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 2011-03-21
    • 1970-01-01
    • 2015-02-25
    相关资源
    最近更新 更多