思考这个问题的方式尝试思考你可以通过哪些方式将这个问题分解为相互依赖的较小问题。首先想到的是根据索引来拆分问题。让我们尝试从左到右(每次调用将索引增加 1)。我们的基本情况是在我们遍历所有元素之后,即数组的末尾。我们需要在那里做什么?相互比较总和,所以我们需要通过这些总和。对于实际的递归调用,有两种可能性,即添加到任一总和的当前元素。我们只需要检查这两个调用,如果有一个返回true,则返回true。
这会导致解决方案没有任何循环,方法是让您的递归函数将当前索引以及两个总和作为参数,并有两种递归情况 - 一种是将当前元素添加到一个总和,以及一个将其添加到另一个总和的位置。然后在到达数组末尾时比较总和。
在 Java 中,它看起来像这样:
boolean canBeDividedEqually(int[] array)
{
return canBeDividedEquallyHelper(array, 0, 0, 0);
}
boolean canBeDividedEquallyHelper(int[] array, int i, int sum1, int sum2)
{
if (i == array.length)
return sum1 == sum2;
return canBeDividedEquallyHelper(array, i+1, sum1 + array[i], sum2) ||
canBeDividedEquallyHelper(array, i+1, sum1, sum2 + array[i]);
}
这可以通过只传递 1 个和并从中添加或减去,然后在最后与 0 进行比较来稍微改进。
请注意,这是the partition problem,这种蛮力解决方案需要指数级时间(即,随着输入大小的增加,它会变得非常缓慢)。