【问题标题】:What is the Big-O complexity of my code?我的代码的 Big-O 复杂度是多少?
【发布时间】:2014-01-04 02:28:14
【问题描述】:

给定一个整数数组,编写一个方法,返回所有加起来为 100 的唯一对。

示例数据:

sample_data = [0, 1, 100, 99, 0, 10, 90, 30, 55, 33, 55, 75, 50, 51, 49, 50, 51, 49, 51]
sample_output = [[1,99], [0,100], [10,90], [51,49], [50,50]]

我这个周末正在解决这个问题,虽然我的解决方案看起来可扩展且高效,但我想确定我的解决方案的最坏情况时间复杂度是多少?

这是我的解决方案:

def solution(arr)
  res = []
  h = Hash.new

  # this seems to be O(N)
  arr.each do |elem|
    h[elem] = true
  end

  # how do I determine what Time complexity of this could be?
  arr.each do |elem|
    if h[100-elem]
      h[100-elem] = false
      h[elem] = false
      res << [elem, 100-elem]
    end
  end
  res 
end

如果两个循环都是 O(N),我将它们相加:O(N + N),这将等于 O(2N),并将 2 作为常数,我可以假设我的解决方案是 O (N) ?

【问题讨论】:

  • 那是正确的。
  • 我认为你的假设基本上是正确的。这也是假设元素可以为负数(并且超过 100 个)以使其有意义 - 否则只有对初始输入进行重复数据删除才会有任何缩放成本,而一旦您填充了所有键 0.. 100。从技术上讲,h[elem] = true 不是O(1)(很多人似乎都这么认为),而是O(log(N)),所以你的整体复杂性可能是O(Nlog(N)) 最坏的情况——你只会看到如果你输入了数百万个整数的数组虽然
  • @NeilSlater 你错了。 h 是一个哈希映射,搜索是线性时间。 Wiki
  • @screenmutt:我在基准测试中看不到这一点。例如array = (0..10000000).map { |x| SecureRandom.random_number( 2000000000 ) - 1000000000 }; Benchmark.bm { |bm| h = Hash.new; bm.report(:five) { 100000.times {|i| h[ array[i] ] = true } }; h = Hash.new; bm.report(:six) { 1000000.times {|i| h[ array[i] ] = true } } } - 事实上我看到了我对 O(Nlog(N)) 的期望 - 解释一下?
  • @NeilSlater 你能解释一下为什么h[elem] = true 可能是O(log(N)) 吗?我的假设和理解是 O(1) 就像你提到的那样。

标签: ruby performance algorithm complexity-theory computer-science


【解决方案1】:

问题可能是关于散列的时间复杂度,但对于特定问题,散列最好实现为由输入 0..sum 索引的布尔数组(在本例中为 100)。这将具有最佳、最差和平均情况常量时间。

这种方法计算复杂度更简单,为 O(N)。

【讨论】:

  • 是的,这是实现解决方案的另一种方式。我也想过这个办法。
  • 我想你会在实践中发现它更快(并且更确定的复杂性计算)。稀疏数组用一点空间(在低 N 时几乎没有)来换取速度。
【解决方案2】:

你是对的。如果您考虑哈希搜索/插入的摊销运行时间,则此代码的大 O 将是 O(n)

如果您采用哈希搜索/插入的最坏情况 (O(n)),那么它将是 O(n^2)

See Wikipedia on Hash Tables

【讨论】:

    猜你喜欢
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2023-03-27
    • 2016-06-30
    • 1970-01-01
    • 2020-03-03
    相关资源
    最近更新 更多