【问题标题】:Why does this method work?为什么这种方法有效?
【发布时间】:2018-04-11 06:36:03
【问题描述】:

这是一种递归回溯方法,用于确定给定数组的总和是否可以达到目标数量。 这有效:

  public boolean groupSum(int start, int[] nums, int target) {
  if(start >= nums.length)
    return target ==0;
  if(!groupSum(start+1,nums,target-nums[start]))
    return groupSum(start+1,nums,target);
  return true;
}

这不是:

  public boolean groupSum(int start, int[] nums, int target) {
  if(start >= nums.length)
    return target ==0;
  if(!groupSum(start+1,nums,target-nums[start]))
    return groupSum(start+1,nums,target);
  return false;
}

该方法如何甚至到达最终的返回语句?

【问题讨论】:

  • 你能强调一下这两个程序的区别吗?我已经找了超过一分钟,我仍然没有看到它......
  • 这是两种方法中的最终返回语句。
  • How does the method even reach the final return statement? - 与第一种方法一样吗?当堆栈耗尽时它最终返回 - 如果没有,你会有一个堆栈溢出。
  • 返回目标==0不应该结束栈吗?
  • !false 等于 true,所以在第二个程序中,您将重复 both groupSum 调用

标签: recursion return-value recursive-backtracking


【解决方案1】:

在您的程序中,您有两个 if 语句,它们最终都会返回。如果两者都为假,则最后一个返回有效。因此,当您点击函数的最后一行时,您可以期望这是真的:

start < nums.length && groupSum(start + 1, nums, target - nums[start])

我想也许更清晰一点的版本是这样的:

public boolean groupSum(int start, int[] nums, int target) {
  if (start >= nums.length)
    return target == 0;
  if (groupSum(start + 1, nums, target - nums[start]))
    return true;
  return groupSum(start + 1, nums, target);
}

这是完全相同的逻辑,只是我最后切换了两个并颠倒了谓词(删除了 not)。

【讨论】:

  • 感谢您抽出宝贵时间回答我的问题,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 2022-08-10
相关资源
最近更新 更多