【问题标题】:Python: Time and space complexity of gcd and recursive iterationsPython:gcd 和递归迭代的时间和空间复杂度
【发布时间】:2018-03-15 16:11:48
【问题描述】:

我正在准备期中考试,这是过去一年大学论文中的一个问题。 (问题如下) 给定欧几里得算法,我们可以写函数gcd。

def gcd(a,b):
    if b == 0:
        return a
    else:
        return gcd(b, a%b)

[约化真分数] 考虑分数 n/d ,其中 n 和 d 是正整数。 如果 n

实现函数 count_fraction,它接受一个整数 n 并返回 n 的约简真分数的个数。假设 gcd 的增长顺序(时间)是 O(logn),那么您在 (B) 部分中编写的函数在时间和空间方面的增长顺序是多少,以 n 表示。解释你的答案。

建议的答案。

def count_fraction(n):
    if n==1:
        return 0
    else:
        new = 0
        for i in range(1,n):
            if gcd(i,n) == 1:
                new += 1
        return new + count_fraction(n-1)

建议的答案很奇怪,因为这个问题在前几年的趋势,旨在测试纯递归/纯迭代解决方案,但它混合了。尽管如此,我不明白为什么建议的增长顺序是这样给出的。 (我会按照格式、建议的答案、我的答案和我的基础问题来写)

时间:O(nlogn),因为大概是log1+log2+····+log(n−1)+logn

我的时间:O(n^2 log n)。由于有 n 个递归函数调用,每个调用都有 n-1 次迭代,由于 gcd,这需要 O(log n) 时间。

问题 1:我认为时间是计算迭代/递归次数* 1 次迭代/递归所花费的时间。这实际上是我第一次与混合迭代/递归解决方案进行交互,所以我并不真正了解交互。谁能告诉我我是对还是错?

空格:O(n),因为 gcd 是 O(1),而且这段代码显然是线性递归的。

我的空间:O(n*log n)。由于 gcd 是 O(log n) 并且此代码占用 O(n) 空间。

问题 2:我认为空间是计算递归次数* 1 次递归调用占用的空间或所有迭代中所需的最大空间量。首先,我认为 gcd 是 O(log n) 因为我假设递归将发生 log n 次。我想问一下这种差异是否是由于我的讲师所说的。

(我真的不明白我的讲师对阶乘递归的延迟操作或迭代中没有形成新对象的说法是什么。那么你如何接受这样一个事实,即在递归中形成了新对象也没有延迟操作迭代)。

如果你能澄清我对为什么 gcd 是 O(1) 而不是 O(log n) 的疑问,我想如果我将 n*1 用于递归情况,我会同意这个答案。

【问题讨论】:

  • 这与您的具体复杂性问题无关,但问题范围的描述似乎完全错误。如果你只是限定n,那么n < d 的真分数是无限的。为什么1/x 不包含在列表中的每个正值x?实际绑定似乎在d,而不是n。或者更确切地说,它们都在:n < d <= bound
  • @Blckknght 我承认我发现 qns 也不清楚,从他们给我的列表中给出。但我只是一个学生,可能考官没有用文字很好地解释上下文。我们应该只使用基于示例的内容吗?我总是这样做,而不是怀疑上下文是否合法。

标签: python-3.x time-complexity


【解决方案1】:

我同意你对运行时间的分析。它应该是O(n^2 log(n)),因为您在每次递归调用count_fraction 时都会调用n 来调用gcd

您对第二个问题也部分正确,但您得出错误的结论(并且由于错误的原因,提供的答案得到了正确的结论)。 gcd 函数确实使用O(log(n)) 空间,用于递归调用的堆栈。但是,该空间会在以后从count_fraction 每次调用gcd 时重复使用,因此只有一个大小为log(n) 的堆栈。所以没有理由将log(n) 乘以任何东西,只需在gcd 调用发生时将其添加到其他可能使用内存的东西中。由于count_fraction的递归调用还会有一个大小为O(n)的堆栈,因此可以删除较小的log(n)术语,所以你说它占用O(n)空间而不是O(n + log(n))

总而言之,我会说这是一个真的糟糕的任务,值得尝试学习。几乎其中的所有内容都在某处有错误,从描述它限制n 而实际上限制d 的描述,到您描述的至少部分错误的答案。

【讨论】:

  • 我想我以前听说过“空间重用”,但我不知道它对空间复杂性的重要性。你怎么知道空间在从count_fractiongcd 的调用中被重用了?介意提供一个“没有空间重复使用”的例子吗?为奇怪的 qns 抱歉。我的大学给了我作业,主要是数学难题的形式,比如 4 个玻璃问题,连分数,河内塔。我通过了其中的一些通过尝试一些我认为可行的代码。我对这些概念的基础知识没有“涵盖”或“培养”,我不确定正确的学习方法。
  • 顺便说一句,我有更多关于空间复杂度的 qns。如果你不介意的话,也许你可以用这个上下文来解释它。谢谢您的帮助。 [stackoverflow.com/questions/49194892/…
猜你喜欢
  • 2023-03-04
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 2017-01-25
  • 1970-01-01
  • 2021-06-27
  • 2018-02-10
相关资源
最近更新 更多