У меня есть полный ответ кода ниже, и вот объяснение:
По сути, вам нужно разбить эту проблему на повторение. Это означает, что вы смотрите на выбор на каждом шаге (то есть использовать число или нет в сумме) и рекурсивно вычисляете оба варианта.
Базовый случай: если num == 0, то мы знаем это так. Но если num! = 0 и длина массива 0, то мы знаем, что это ложь.
Рекурсивный случай: мы проверяем, меньше ли первое число в массиве num или равно ему. Если нет, то мы не сможем его использовать. Итак, мы выполняем рекурсивный вызов со всеми теми же параметрами, за исключением того, что массив теперь является исходным массивом за вычетом первого числа
Если мы МОЖЕМ использовать номер (например, a[0] <= num
), то в истинном ответе может использоваться это или оно не может его использовать. Мы выполняем рекурсивный вызов для каждого случая и возвращаем истину, если какой-либо из рекурсивных вызовов возвращает истину.
Правило последовательного числа: это легко реализовать. Мы добавляем параметр под названием «left», который сообщает нам количество элементов, которые мы можем последовательно взять из начала массива. Для начала осталось 2, потому что мы можем взять не более 2 последовательных чисел. Затем в случаях, когда мы ДЕЙСТВИТЕЛЬНО используем первое число в массиве в нашей сумме, мы уменьшаем влево. Если мы не используем первое число в массиве, мы сбрасываем left до 2. В случаях, когда left становится 0, у нас нет другого выбора, кроме как пропустить текущее число в верхней части массива.
class Main {
public static void main(String[] args) {
int[] a = new int[] {5,4,2,1,3};
System.out.println(sumRule(a, 8));
System.out.println(sumRule(a, 11));
}
public static boolean sumRule(int[] a , int num){
if (num == 0){
return true;
} else {
return sumRule(a,num,2);
}
}
private static boolean sumRule(int[] a, int num, int left){
if (num == 0) {
return true;
}
if (a.length == 0) {
return false;
}
int[] a_new = new int[a.length-1];
for (int i = 1; i < a.length; i++) a_new[i-1] = a[i];
if (left == 0) {
return sumRule(a_new, num, 2);
}
boolean using_a0 = false;
if (a[0] <= num) {
using_a0 = sumRule(a_new, num-a[0], left-1);
}
boolean not_using_a0 = sumRule(a_new, num, 2);
return (not_using_a0 || using_a0);
}
}
Изменить - вариант приведенного выше кода без копирования массива:
class Main {
public static void main(String[] args) {
int[] a = new int[] {5,4,2,1,3};
System.out.println(sumRule(a, 8));
System.out.println(sumRule(a, 11));
}
public static boolean sumRule(int[] a , int num){
if (num == 0){
return true;
} else {
return sumRuleNoLoop(a,num,2,0);
}
}
private static boolean sumRuleNoLoop(int[] a, int num, int left, int startIdx){
if (num == 0) {
return true;
}
if (startIdx >= a.length) {
return false;
}
if (left == 0) {
return sumRuleNoLoop(a, num, 2, startIdx+1);
}
boolean using_a0 = false;
if (a[startIdx] <= num) {
using_a0 = sumRuleNoLoop(a, num-a[startIdx], left-1, startIdx+1);
}
boolean not_using_a0 = sumRuleNoLoop(a, num, 2, startIdx+1);
return (not_using_a0 || using_a0);
}
}