Oto pomysł:
- Sortuj 2nd do N-te elementy malejące (problem pozostaje taka sama).
- Utwórz sumę skumulowaną w odwrotnej kolejności. [1 4 3 2] => [10 9 5 2], aby uzyskać górną granicę dla najwyższego numeru, który wciąż możesz osiągnąć z pozostałymi liczbami całkowitymi.
- Użyj granic z sumy skumulowanych zwrotów do przycinania.
W Javie:
// assuming the numbers are positive
// (ignore operator when parsing, line.split("[ +-]+") will do)
public static int canReach0(int[] numbers) {
sort(numbers, 1); // sort(array, offset) doesn't matter what algorithm
// for 300 elements and compared to the complexity of the rest
int[] revSum = new int[numbers.length];
revSum[numbers.length - 1] = numbers[numbers.length - 1];
for (int i = numbers.length - 2; i >= 0; i--)
revSum[i] = revSum[i + 1] + numbers[i];
int sum = numbers[0];
if (sum == revSum[1])
return 0;
return solve(numbers, 1, sum, revSum);
}
private static int solve(int[] numbers, int index, int sum, int[] revSum) {
if (index == numbers.length - 1)
return -1;
int high = sum + numbers[index];
if (high == revSum[index + 1] ||
(high < revSum[index + 1] && solve(numbers, index + 1, high, revSum) == 0))
return 0;
int low = sum - numbers[index];
if (low == -revSum[index + 1] ||
(low > -revSum[index + 1] && solve(numbers, index + 1, low, revSum) == 0))
return 0;
return -1;
}
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest to tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. - [Z recenzji] (/ recenzja/niskiej jakości-posty/13205501) – manetsus
@manetsus - Tekst odpowiedzi podaje zasadniczą kwestię, na którą wskazuje problem, na który stara się odpowiedzieć OP. W tym przypadku link nie jest konieczny, aby odpowiedzieć na pytanie; to tylko lukier na torcie. – borrible