我正在研究一种算法,我们给出了两个输入,一个总量和一个功率值。我们必须在power参数中找到唯一的数字组合总数,总计达总量。
例如: 给定数量= 10且功率= 2,只有一个独特的解决方案: (1 ^ 2)+(3 ^ 2)= 10
(问题来自:https://www.hackerrank.com/challenges/the-power-sum)
到目前为止,这是我的算法:
def count_unique_combos(total, candidate, power)
return -1 if total < 0 || candidate > total # this means impossible to continue
return 1 if total == 0 # arrived at our goal
num_ways = 0
# all the ways to get the total amount, if we use candidate ** power
with_candidate = count_unique_combos(total - candidate ** power, candidate + 1, power)
num_ways += with_candidate if with_candidate != -1
# all the ways to get the total amount without using the candidate.
without_candidate = count_unique_combos(total, candidate + 1, power)
num_ways += without_candidate if without_candidate != -1
num_ways
end
这是我很困惑的事情。我已经阅读了很多关于递归算法的信念跳跃的内容,你假设你有这个函数用于N-1输入,你只需要使它适用于输入大小N并放入正确的基本情况。
基础案例对我来说似乎是合理的,递归关系也是如此(用这个数字得到所有独特的组合,得到所有没有这个数字的组合)。
但是,我的输出不正确。对于金额= 10且功率= 2,我的结果值为零。有谁知道我在逻辑上没有接近这个?
答案 0 :(得分:1)
尝试交换你的基本案例
return 1 if total == 0 # arrived at our goal
return -1 if total < 0 || candidate > total # this means impossible to continue
当total == 0
你传入的任何候选人(因为你只增加候选人)将是candidate > total
并且在你检查你是否已经到达之前你将以-1开出积极的基础案例。
当你交换它们时(使用tadman的测试用例,为了便于比较)
count_unique_combos(10, 1, 2)
# => 1
count_unique_combos(100, 1, 2)
# => 3
count_unique_combos(100, 1, 3)
# => 1
答案 1 :(得分:1)
当你谈论数字集时,特别是当它与排列和/或组合有关时,依靠combination
这样的核心Ruby函数要容易得多:
def power_sum(total, power)
set = (1..total).to_a
(1..set.length).flat_map do |size|
set.combination(size).to_a
end.select do |numbers|
numbers.inject(0) { |s, n| s + n ** power } == total
end
end
然后根据测试用例:
power_sum(10, 2)
# => [[1, 3]]
power_sum(100, 2)
# => [[10], [6, 8], [1, 3, 4, 5, 7]]
power_sum(100, 3)
# => [[1, 2, 3, 4]]
如果您只关心多少,请在最后致电.length
。
这里可以采用递归方法,但是你处理它的方式似乎并没有正确处理这些组合。您需要有两种不同的递归方法,适用于N大小的子集。