Идея рекурсивного метода canFind()
:
- Если я обработал числа до позиции
index
и
пока собрали две суммы sumOne
и sumTwo
, возможно ли
найти решение с оставшимися номерами?
Прежде чем подробно рассмотреть ваш код, давайте уточним задачу (если я правильно понимаю): для правильного решения необходимо подсчитать каждое число либо в sumOne
, либо в sumTwo
. Пропуск числа или подсчет числа в обеих суммах не допускаются.
Итак, в любой момент процесса решения у вас есть выбор: добавить текущий номер в sumOne
или в sumTwo
, и это то, что вы правильно делаете в двух рекурсивных вызовах
canFind(nums, index + 1, sumOne + nums[index], sumTwo)
и
canFind(nums, index + 1, sumOne, sumTwo + nums[index])
Но есть проблема с вызовами. Вы не можете знать, будет ли правильное добавление текущего номера к sumOne
или sumTwo
для решения, поэтому вы должны попробовать оба способа и вернуть true, если один из них завершится успешно. Ваш код добавляет к sumOne
, если он меньше, в противном случае к sumTwo
. Хотя это кажется правдоподобным, это не обязательно приводит к решению. Таким образом, вы должны изменить эту часть на
if (canFind(nums, index + 1, sumOne + nums[index], sumTwo)) {
// if there's some solution by adding to sumOne, we're finished.
return true;
} else if (canFind(nums, index + 1, sumOne, sumTwo + nums[index])) {
// if there's some solution by adding to sumTwo, we're finished.
return true;
} else {
// if both tries didn't succeed, thre's no solution
// starting from the given situation
return false;
}
Как долго мы должны продолжать пробовать числа? Пока мы не доберемся до конца массива, так как нам не разрешено пропускать любое число.
И когда мы достигаем конца массива, у нас есть решение или нет? Это решение, если обе суммы равны.
Итак, прежде чем пытаться выполнить рекурсивные вызовы, мы должны проверить конец массива:
if (index == nums.length) {
if (sumOne == sumTwo) {
return true;
} else {
return false;
}
}
Собираем все вместе:
private static boolean canFind(int[] nums, int index, int sumOne, int sumTwo) {
if (index == nums.length) {
// if we're at the end of the array, we can compare the sums
// to decide whether this is a solution.
if (sumOne == sumTwo) {
return true;
} else {
return false;
}
}
if (canFind(nums, index + 1, sumOne + nums[index], sumTwo)) {
// if there's some solution by adding to sumOne, we're finished.
return true;
} else if (canFind(nums, index + 1, sumOne, sumTwo + nums[index])) {
// if there's some solution by adding to sumTwo, we're finished.
return true;
} else {
// if both tries didn't succeed, thre's no solution
// starting from the given situation
return false;
}
}
Это должно в основном делать работу.