【问题标题】:Big O Complexity of Algorithm算法的大 O 复杂度
【发布时间】:2017-02-20 04:25:49
【问题描述】:

此方法试图将 num 表示为 arr 中元素的乘积。

例如 method1(37,[1,3,5]) 返回 [2,0,7]

// arr is an array of divisors sorted in asc order, e.g. [1,3,5] 
def method1(num, arr) 
  newArr = Array.new(arr.size, 0)
  count = arr.size - 1

  while num > 0
    div = arr[count]  

    if div <= num
      arr[count] = num/div
      num = num % div
    end 

    count = count - 1
  end 

  return newArr
end 

如果您能帮我推导出算法的复杂性,我将不胜感激。也请随时提高我的算法的效率

【问题讨论】:

  • 计数在哪里初始化?
  • 确定 Big-O 表示法的经验法则:如果将输入的大小加倍,算法还需要做多少工作:(a) 如果输入完全相同,它可能是 O(1)。 (b) 如果它输入两倍,它可能是 O(n)。 (c) 如果它是输入的四倍,它可能是 O(n^2)。
  • 哦忘了在此处包含计数。谢谢
  • @X.enia:您的意思是增加count 变量而不是在while 循环内减少吗?
  • 对我来说看起来像 N 次,它基本上是在数组上循环一次对吗?

标签: ruby algorithm big-o code-complexity


【解决方案1】:

这是您的代码的重构版本:

def find_linear_combination(num, divisors)
  results = divisors.map do |divisor|
    q, num = num.divmod(divisor)
    q
  end
  results if num == 0
end

puts find_linear_combination(37, [5, 3, 1]) == [7, 0, 2]
puts find_linear_combination(37, [1, 3, 5]) == [37, 0, 0]
puts find_linear_combination(37, [5]).nil?

由于n 的大小与divisors 相同,因此该算法显然是O(n)。只有一个循环 (map),循环内只有一个整数除法。

请注意,除数应按降序编写。如果没有找到线性组合,则该方法返回 nil。

如果您想对divisors 进行排序,算法将是O(n*log n)。如有必要,附加 1 (O(1)) 也是一个好主意。

【讨论】:

  • 感谢您的回复!除数不是问题,因为它可以假设已经按升序排序
【解决方案2】:

您可以这样做:

def method1(num, arr)

    newArr = Array.new(arr.size, 0)
    count = arr.size()-1

    while num>0
        div = arr[count]

        if div <= num
            arr[count] = num / div
            num = num % div
        end

        count = count + 1
    end
    return arr
end


ar = Array.new(25000000) { rand(1...10000) }

t1 = Time.now
method1(37, ar)
t2 = Time.now

tdelta = t2 - t1

print tdelta.to_f

输出:

0.102611062

现在将数组大小加倍:

ar = Array.new(50000000) { rand(1...10) }

输出:

0.325793964

再加倍:

ar = Array.new(100000000) { rand(1...10) }

输出:

0.973402568

所以n 加倍,持续时间大约增加三倍。由于 O(3n) == O(n),所以 整个算法在 O(n) 时间内运行,其中 n 表示输入的大小 数组。

【讨论】:

  • 我明白了,这很有用!非常感谢您的帮助!
  • O(3n) 应该是 O(1.5n),但无论如何它是 O(n)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 2011-06-05
  • 2020-01-07
相关资源
最近更新 更多