计算缺失的数字

时间:2013-05-25 23:25:23

标签: ruby

这是练习:

  

您已获得1到10,000的序列号列表,但是   他们都乱了;此外,缺少一个数字   从列表中。任务的目的是找出哪个数字   丢失。

The strategy这个问题是对数组中的元素求和,然后将范围加1到10,000,并减去差值。这等于缺少的数字。计算1..nn(n+1)/2的范围总和的公式。

这是我目前的做法:

def missing_number(array)
  sum = 0
  array.each do |element|
  sum += element
  end

  ((10000*10001)/2) - sum
end

当我输入一个如下数组的输出时,我被绊倒的地方是:

puts missing_number(*1..10000) #=> 0 

为什么会这样?

谢谢!

4 个答案:

答案 0 :(得分:3)

无需对数组进行排序。长度为N的数组应该只包含其中一个数字1..(N+1),因此数组长度+ 1是确定如果所有值都在那里的话,那么grand_sum的基础。

def missing_number(array)
  grand_sum = (array.length + 1) * (array.length + 2) / 2
  grand_sum - array.inject(:+)
end

<强>附录

此方法将数组作为参数,而不是范围。您不能直接使用范围,因为不会有缺失值。在调用该方法之前,您需要一些机制来生成满足问题描述的数组。这是一个可能的解决方案:

PROBLEM_SIZE = 10_000
# Create an array corresponding to the range
test_array = (1..PROBLEM_SIZE).to_a
# Target a random value for deletion -- rand(N) generates values in
# the range 0..N-1, inclusive, so add 1 to shift the range to 1..N
target_value = rand(PROBLEM_SIZE) + 1
# Delete the value and print so we can check the algorithm
printf "Deleting %d from the array\n", test_array.delete(target_value)
# Randomize the order of remaining values, as per original problem description
test_array.shuffle!
# See what the missing_number() method identifies as the missing number                     
printf "Algorithm identified %d as the deleted value\n", \
       missing_number(test_array)

答案 1 :(得分:1)

解决问题的另一种方法,如果它不具有性能关键性,因为它具有可读性:

def missing_number(array)
  (1..10_000).to_a - array
end

答案 2 :(得分:0)

而不是*1..10000,参数应为(1..10000).to_a

答案 3 :(得分:0)

你不应该使用*1..10000,这只会扩展到10,000个参数。 (1..10000).to_a将返回零,因为您需要删除之一的1..10000之间缺少任何元素。下面是一些详细解释的代码。

def missing_number array
  # put elements in order                                                                
  array.sort!

  # get value of last array element                                                      
  last  = array[-1]

  # compute the expected total of the numbers                                            
  # 1 - last 
  # (n + 1)(n)/2                                                               
  expected = (last + 1) * (last / 2)

  # actual sum                                                                           
  actual = array.inject{|sum,x| sum + x}

  # find missing number by subtracting                                                   
  (expected - actual)
end

test = (1..10000).to_a
test.delete 45
puts "Missing number is: #{missing_number(test)}"