【问题标题】:Time complexity vs Space complexity时间复杂度与空间复杂度
【发布时间】:2016-02-13 10:21:11
【问题描述】:

我试图从一个简短的算法中理解时间复杂度和空间复杂度之间的区别。此代码采用列表/数组并返回出现奇数次的单个数字。在 Python 中:

def foo(array_of_ints):
    hash_table = dict()
    for i in array_of_ints:
        hash_table[i] = hash_table.setdefault(i, 0) + 1
    for key, value in hash_table.items():
        if value%2 != 0:
            return key

有两个循环遍历数组的长度。但是第一个循环只是在内存中创建一个哈希表/字典。时间复杂度也是 O(n^2),因为我们两次迭代长度为 n 的数组,还是时间复杂度和空间复杂度各为 O(n),因为第一个循环只是在内存中创建了一个新的数据结构?

【问题讨论】:

  • 迭代 N 两次是 O(2*N) = O(N),而不是 N^2
  • 不是答案,但算法可以改进为O(1) 空间,只需对所有整数进行异或运算并返回结果。
  • 这是家庭作业吗?
  • 你可以使用hash_table = collections.Counter(array_of_ints)。 @user2357112:你的意思是return reduce(lambda acc, i: acc ^ i, array_of_ints)
  • @J.F.Sebastian:差不多。所有出现偶数次的元素都会取消。

标签: python algorithm time-complexity space-complexity


【解决方案1】:

时间复杂度也是 O(n^2),因为我们两次迭代 长度为 n 的数组

时间复杂度是你的代码不是O(N²)

迭代长度为N 的集合在时间复杂度上被认为是O(N)。原因是,在 Big-Oh 表示法中,您总是对 支配 函数的术语感兴趣。当您达到足够大的N 时,常量对整体性能的影响开始变得越来越小。

不是说它们“不重要”;只是,由于N 趋于无穷大,这些常数的实际效果更类似于向海洋中再添加一滴或一桶水。该符号旨在让您粗略(不准确)理解算法期望的行为 - 即随着输入大小的增长,它缩放的效果如何。

这意味着您的函数可以在同一个集合上迭代 5 次,它会是 O(5N),它仍然是 O(N)

但是你怎么得到O(N²)呢?您会开始将这些视为您开始将循环嵌套彼此之间。

示例A - O(N)

def linear(integers):
    # no nesting
    for i in integers: print(i)
    for i in integers: print(i+1)

示例B - O(N²)

def quadratic(integers):
    # notice double nesting
    for i in integers:
        for j in integers:
            print(i+j)

示例C - O(N³)

def cubed(integers):
    # notice triple-nesting
    for i in integers:
        for j in integers:
            for k in integers:
                print(i+j+k)

如果您使用矩阵,您会发现O(N³) 算法的示例,至少如果您使用的是幼稚的实现。如果您不清楚,这称为asymptotic notation

还要注意Big-Oh notation 表示算法运行时间的上限。这意味着它是衡量其最坏情况的一个指标。

例如,线性搜索列表中不存在的项目将使您的算法达到其上限O(N),因为它必须检查列表中的每个元素。

或者说时间复杂度和空间复杂度都是 > O(n),因为第一个循环只是在内存中创建了一个新的数据结构?

在这种情况下,循环所做的事情本身与测量无关。相关的是这里占主导地位的操作,这是使循环工作的比较和增量。例如,value % 2 != 0 是一个常数时间运算¹,或 O(1),不会对代码的运行时间产生任何实质性影响。

那么什么是空间复杂度?

所需的空间还取决于输入的大小和内容。您的算法最糟糕的情况是 distinct 整数数组,这意味着每个值都是唯一的。

如果每个值都是唯一的,那么每个值都会导致添加一个键/值对。因此,该算法需要O(N)空间。

请注意,它可能会更少,但大 O 表示法会传达 上限

请记住,通常情况下,时间/空间限制之间也存在权衡,其中更快的算法可能需要更多内存,而内存效率更高的替代方案可能需要更多时间。


¹这假设我们已将算术运算(如 +-/*% 等)定义为 基本运算 .

【讨论】:

  • 那么什么是空间复杂度?
  • @kevin:如果你认为正在使用的空间是输入大小的函数,你觉得它是什么样的?这是相同的概念,但适用于空间而不是运行时间。
【解决方案2】:

在大 O 表示法中,2nn 不被认为是不同的,因此该算法具有 O(n) 行为。要具有O(n^2) 行为,您的算法必须为数组中的每个元素遍历/构造整个数组一次。另一种说法是,您需要嵌套循环来实现O(n^2)

【讨论】:

    【解决方案3】:

    时间和空间复杂度都是O(n)。

    【讨论】:

    • 投反对票的人能否告诉我,为什么我的回答被投反对票?
    • 答案缺乏解释,对阅读此问题的任何人都没有真正的用处。
    猜你喜欢
    • 2018-08-02
    • 2012-08-14
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多