功率和递归算法

时间:2017-07-13 20:10:03

标签: ruby algorithm recursion

我正在研究一种算法,我们给出了两个输入,一个总量和一个功率值。我们必须在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,我的结果值为零。有谁知道我在逻辑上没有接近这个?

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大小的子集。