我正在浏览一些面试问题并在一个网站上遇到过这个问题。我已经提出了Ruby的解决方案,我想知道它是否有效并且是一个可接受的解决方案。我现在已经编写了一段时间,但从未专注于解决方案的复杂性。现在我正在努力学习最小化时间和空间的复杂性。
问题: 你有一个整数数组,并且对于每个索引,你想要找到除了该索引处的整数之外的每个整数的乘积。
示例:
arr = [1,2,4,5]
result = [40, 20, 10, 8]
# result = [2*4*5, 1*4*5, 1*2*5, 1*2*4]
考虑到这一点,我提出了这个解决方案。
解决方案:
def find_products(input_array)
product_array = []
input_array.length.times do |iteration|
a = input_array.shift
product_array << input_array.inject(:*)
input_array << a
end
product_array
end
arr = find_products([1,7,98,4])
根据我的理解,我访问数组的次数与其长度一样多,这在效率和速度方面被认为是可怕的。我仍然不确定我的解决方案的复杂程度。
任何有助于提高效率的帮助都是值得赞赏的,如果您还能说出我的解决方案的复杂性以及如何计算,那就更好了。
由于
答案 0 :(得分:3)
def product_of_others(arr)
case arr.count(0)
when 0
total = arr.reduce(1,:*)
arr.map { |n| total/n }
when 1
ndx_of_0 = arr.index(0)
arr.map.with_index do |n,i|
if i==ndx_of_0
arr[0,ndx_of_0].reduce(1,:*) * arr[ndx_of_0+1..-1].reduce(1,:*)
else
0
end
end
else
arr.map { 0 }
end
end
product_of_others [1,2,4,5] #=> [40, 20, 10, 8]
product_of_others [1,-2,0,5] #=> [0, 0, -10, 0]
product_of_others [0,-2,4,5] #=> [-40, 0, 0, 0]
product_of_others [1,-2,4,0] #=> [0, 0, 0, -8]
product_of_others [1,0,4,0] #=> [0, 0, 0, 0]
product_of_others [] #=> []
对于arr
不包含零的情况,我使用arr.reduce(1,:*)
而不是arr.reduce(:*)
,以防数组为空。同样,如果arr
包含一个零,我使用.reduce(1,:*)
以防零位于数组的开头或结尾。
答案 1 :(得分:2)
对我来说最简单(而且相对有效)似乎首先得到了总产品:
total_product = array.inject(1){|product, number| product * number}
然后将每个数组元素映射到total_product
除以元素:
result = array.map {|number| total_product / number}
初步计算total_product = 1*2*4*5
后,这将计算
result = [40/1, 40/2, 40/4, 40/5]
据我记得,这总计为O(n)[创建总产品:触摸每个数字一次] + O(n)[每个数字创建一个结果:触摸每个数字一次]。 (如果我错了,纠正我)
<强>更新强>
正如@hirolau和@CarySwoveland指出的那样,如果输入中有(正好为1)0,则存在问题:
zero_count = array.count{|number| number == 0}
if zero_count == 0
# as before
elsif zero_count == 1
# one zero in input, result will only have 1 non-zero
nonzero_array = array.reject{|n| n == 0}
total_product = nonzero_array.inject(1){|product, number| product * number}
result = array.map do |number|
(number == 0) ? total_product : 0
end
else
# more than one zero? All products will be zero!
result = array.map{|_| 0}
end
很抱歉,现在这个答案基本上等于@CarySwoveland,但我认为我的代码更明确。 请查看有关进一步性能考虑的评论。
答案 2 :(得分:0)
我将如何做到这一点:
arr = [1,2,4,5]
result = arr.map do |x|
new_array = arr.dup # Create a copy of original array
new_array.delete_at(arr.index(x)) # Remove an instance of the current value
new_array.inject(:*) # Return the product.
end
p result # => [40, 20, 10, 8]
答案 3 :(得分:-2)
我不知道ruby,但是,访问数组是O(1),这意味着它处于恒定时间,因此算法的复杂性为O(n),非常好。我不认为在复杂性方面可以找到更好的解决方案。真正的速度是另一个问题,但这个解决方案很好