【问题标题】:Issue returning proper value问题返回正确的值
【发布时间】:2014-11-06 00:54:35
【问题描述】:
def sum_two(arry, sum)
  p check_sums(sum, arry[0], arry[1..arry.length - 1])
end

def check_sums(target, first_num, remaining_nums)
  result = []
  return result if remaining_nums == []

  remaining_nums.each do |n|
    if first_num + n == target
      result << [first_num, n]
    end
  end
  check_sums(target, remaining_nums[0], remaining_nums[1..remaining_nums.length - 1])
end

my_arry = [2,4,6,1,3,5,7]
my_sum = 6

sum_two(my_arry, my_sum)

以上是我对练习面试问题的解答。但是,输出始终是一个空数组 ([])。我的问题似乎很简单,因为我只需要返回最终结果数组,所以我必须遗漏一些明显的东西。基本上,我无法弄清楚为什么它会打印一个空数组,因为我觉得逻辑是合理的。

更新:

下面是我的解决方案的更新版本,其中我将方法包装在一个类中并将结果作为实例变量,以便我可以在整个递归调用过程中保持其状态。感谢@BenE 提到每次递归调用通过时我都会重置值。这真的为我清除了它!这是我的新解决方案:

class SumTwo
  @result = []

  def self.sum_two(arry, sum)
    p SumTwo.check_sums(sum, arry[0], arry[1..arry.length - 1])
  end

  def self.check_sums(target, first_num, remaining_nums)
    return @result if remaining_nums == []

    remaining_nums.each do |n|
      if first_num + n == target
        @result << [first_num, n]
      end
    end
    check_sums(target, remaining_nums[0], remaining_nums[1..remaining_nums.length - 1])
    @result
  end
end
my_arry = [2,4,6,1,3,5,7]
my_sum = 6

SumTwo.sum_two(my_arry, my_sum)

【问题讨论】:

  • 解决方案是否应该是递归的?
  • 面试题是什么?
  • @seph 据我了解,问题要求他检查数组my_arry 中两个数字的总和是否等于my_sum。如果两个数的和相等,则返回这两个数
  • 递归函数的主要问题是结果存储在每个函数调用的本地,因此基本上每次递归调用都会清除结果。
  • @seph 面试问题是:给定一个数字数组和一个目标总和,编写一个函数,返回一个包含所有潜在数字对的新数组。

标签: ruby scope return


【解决方案1】:

问题是您不返回循环使用的 result 数组,仅当 remaning_nums 为空时才返回它,这是您代码的有效解决方案:

def sum_two(arry, sum)
  p check_sums(sum, arry[0], arry[1..arry.length - 1],[])
end

def check_sums(target, first_num, remaining_nums,result)
  return result if remaining_nums == []

  remaining_nums.each do |n|
    if first_num + n == target
      result << [first_num, n]
    end
  end
  check_sums(target, remaining_nums[0], remaining_nums[1..remaining_nums.length - 1],result)
  result
end

my_arry = [2,4,6,1,3,5,7]
my_sum = 6

sum_two(my_arry, my_sum)

【讨论】:

  • 谢谢,但这个结果只向我展示了一个可能的解决方案,[[2,4]],但我想要所有可能的组合,我知道[1, 5] 是另一个
【解决方案2】:

如果你想返回一个数组中的所有数字对,其总和为给定值,我认为最简单的方法是使用Array#combination

def sum_two(arry, sum)
  arry.combination(2).select { |i,j| i+j == sum }
end

sum_two [2,4,6,1,3,5,7], 6
  #=> [[2, 4], [1, 5]]

sum_two [*(1..24)], 12
  #=> [[1, 11], [2, 10], [3, 9], [4, 8], [5, 7]]

sum_two [1,3, 6, 8, 2, 9, 3, 5, 7, 8, 16], 17
  #=> [[1, 16], [8, 9], [9, 8]]

如果您想消除上一个示例中的[8, 9][9, 8],您可以这样做:

def sum_two(arry, sum)
  arry.uniq.combination(2).select { |i,j| i+j == sum }
end

sum_two [1,3, 6, 8, 2, 9, 3, 5, 7, 8, 16], 17
  #=> [[1, 16], [8, 9]]

【讨论】:

  • 这是我对 Ruby 采取的方法。从最初的问题来看,仍然不清楚答案是否需要递归解决方案;不使用组合等方法。
  • 谢谢@BenE!很高兴知道,但我没有使用内置的 ruby​​ 方法来解决它。递归调用只是一种方法,我知道随着数组数字的增加,您将面临堆栈溢出的问题。但我肯定会将此添加到我可能的解决方案中。
  • "...我在不使用内置 Ruby 方法的情况下解决了这个问题。"嗯。在不使用任何内置方法的情况下用 Ruby 编写程序是非常具有挑战性的。 :-) 使用eachcombination 有什么区别?
  • 组合更简洁;-)。但是我听说过很多面试会特别要求你不要使用内置方法来应对特定挑战的情况。这是我不使用组合的唯一原因。
  • 但是如果他们期望你使用combination或类似的东西怎么办?你不会因为建议不那么像 Riby 的东西而给人留下深刻印象。无论如何,问题中没有任何内容表明您不希望使用某些方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 2016-10-09
  • 2021-10-26
相关资源
最近更新 更多