这是练习:
您已获得1到10,000的序列号列表,但是 他们都乱了;此外,缺少一个数字 从列表中。任务的目的是找出哪个数字 丢失。
The strategy这个问题是对数组中的元素求和,然后将范围加1到10,000,并减去差值。这等于缺少的数字。计算1..n
为n(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
为什么会这样?
谢谢!
答案 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)}"