我只是做了一个热身,我偶然发现了这个:
http://codingbat.com/prob/p145416
这三种方法的区别在于我如何在递归调用中添加start参数。
我最初使用列出的第二个函数解决了它,但它给了我臭名昭着的stackoverflow错误。第一个没有给我一个stackoverflow错误。这个网站有什么问题,或者是否存在差异1和2,即Java语言的一个微妙的部分?
public boolean groupSum(int start, int[] nums, int target) {
if (start >= nums.length)
return (target == 0);
return groupSum(start+1, nums, target - nums[start]) || groupSum(start+1,
nums, target);
}
------------这些导致堆栈溢出错误--------------
public boolean groupSum(int start, int[] nums, int target) {
if (start >= nums.length)
return (target == 0);
return groupSum(start++, nums, target - nums[start]) || groupSum(start++,
nums, target);
}
public boolean groupSum(int start, int[] nums, int target) {
if (start >= nums.length)
return (target == 0);
return groupSum(++start, nums, target - nums[start]) || groupSum(++start,
nums, target);
}
答案 0 :(得分:4)
这是一个臭名昭着的微妙错误。看看这个递归调用:
groupSum(start++, nums, target - nums[start])
请注意,您将start++
作为第一个参数传递。这使用后缀++
运算符,它执行以下操作:
start
,然后start
曾经拥有的值。换句话说,这会将start
的本地副本更新为start + 1
,然后将旧值start
传递给递归调用。这意味着start
永远不会在调用之间发生变化,因此基本情况永远不会触发,因此堆栈溢出。您可以通过在函数顶部放置System.out.println
语句来确认这一点。
这里可能还有其他问题,但我怀疑这是你的罪魁祸首。
希望这有帮助!
答案 1 :(得分:1)
++start
(称为预增量)评估为start+1
。 start++
(称为后增量,如增量在评估后完成)评估为start
。他们都将变量中的值设置为start+1
作为评估的副作用。因此,当您执行start++
时,您将start
传递给方法的下一次调用,该方法将start
传递给方法的下一次调用...您永远不会到达基本情况而您无限地递归。