Давайте посмотрим на ваше время l oop:
LinkedList<Integer> result = new LinkedList<Integer>();
boolean b = false;
// Some code omitted here.
while (b = false)
{
c = (int) Math.cbrt(n - sum);
seen.add(c);
method(n, c, seen);
if (sum == n)
{
result = seen;
return true;
}
else
{
return false;
}
}
Во-первых, с while
l oop, который всегда имеет false
в качестве условия цикла, он ничего не делает вообще.
В любом случае, даже если мы притворимся, что пробеги l oop, независимо от того, какая ветвь взяла if
, return
будет достигнуто. Итак, ваш while
l oop вообще не l oop, даже если его условие было изменено на всегда true
. Кроме того, единственное значение, когда-либо присвоенное переменной b
, это false
, и оно вообще ни для чего не используется.
Кроме того, список result
во втором методе всегда пуст. И, поскольку инструкция result = seen;
находится прямо перед return
, это безобидная инструкция, которая делает result
просто бесполезным.
Кроме того, посмотрите на вызов method(n, c, seen);
. Он ничего не делает с его возвращаемым значением! Таким образом, даже если в конечном итоге он вернет true
, вы все равно продолжите работу, в результате чего будет сгенерировано false
.
Кроме того, всякий раз, когда вы добавляете значение к seen
, оно никогда не будет удалено. Поскольку seen
всегда является одним и тем же списком в каждом из рекурсивных вызовов методов, после добавления туда неправильного номера он никогда не будет удален, чтобы освободить место для чего-то другого.
С этим я Я должен заключить, что ваш алгоритм настолько сломан, что его нужно переписать с нуля.
Кроме того, хотя ваш вопрос не очень ясен, я предполагаю, что все найденные числа должны быть разными. В противном случае можно получить 2 = 1<sup>3</sup> + 1<sup>3</sup>
, и каждое число, большее единицы, может быть представлено суммой множества кубов (т. Е. n = 1<sup>3</sup> + 1<sup>3</sup> + 1<sup>3</sup> + ...
).
Алгоритм такой:
- Первый шаг состоит в том, чтобы
for
считал i
с cbrt(n)
до 1, пытаясь сформировать кубы. - Затем вычтите куб из
n
и рекурсивно попытайтесь найти сумма куба для полученного числа. - Добавьте параметр, чтобы избежать повторения чисел, который на единицу меньше, чем последнее использованное число.
- Когда куб сформирован, верните число, которое его сформировало. Во внешних вызовах добавьте результат в список непустых внутренних рекурсивных вызовов.
- Если внутренний рекурсивный вызов выдает пустой список в качестве результата, то текущая итерация
for
вызвала ошибку число, и мы должны попробовать следующий (если у нас есть следующий). - Если
for
заканчивается без формирования куба, вернуть пустой список.
Вот код:
import java.util.LinkedList;
import java.util.List;
public class Main {
public static List<Integer> findCubeSum(int n) {
return findCubeSum(n, n);
}
public static List<Integer> findCubeSum(int n, int max) {
if (n <= 0) return List.of();
int c = (int) Math.cbrt(n);
for (int i = Math.min(c, max); i > 0; i--) {
int x = i * i * i;
if (x == n) {
List<Integer> result = new LinkedList<>();
result.add(i);
return result;
}
List<Integer> result = findCubeSum(n - x, i - 1);
if (result.isEmpty()) continue;
result.add(0, i);
return result;
}
return List.of();
}
public static void main(String[] args) {
System.out.println(findCubeSum(8)); // [2]
System.out.println(findCubeSum(64)); // [4]
System.out.println(findCubeSum(1000)); // [10]
System.out.println(findCubeSum(1072)); // [10, 4, 2]
System.out.println(findCubeSum(1944)); // [12, 6]
System.out.println(findCubeSum(4)); // []
System.out.println(findCubeSum(0)); // []
System.out.println(findCubeSum(-1)); // []
System.out.println(findCubeSum(10)); // []
}
}
См. это работает на ideone .