Эта проблема может быть решена в O (N * log (N)). Самая дорогая операция в этом случае будет сортировать ваш массив. Если ваш домен позволяет использовать не сравнительные виды, например counting sort, то вы сможете сократить временную сложность всего решения до линейного времени.
Идея состоит в том, что в отсортированном массиве вы можете последовательно перебирать элементы в восходящем и нисходящем порядке и, следовательно, находить все пары с минимальной/максимальной суммой в линейном времени. Единственным недостатком такого подхода в применении к вашей задаче является то, что вам нужно найти минимальное абсолютное значение суммы, что означает поиск минимума среди положительных сумм и максимума среди отрицательных сумм. Это потребует двух линейных проходов.
Мое решение ниже. Он проверяется на рандомизированных данных против решения грубой силы O (N^2).
// note: mutates argument!
static Solution solve(int a[]) {
Arrays.sort(a);
int i = 0;
int j = a.length - 1;
// -1 indicates uninitialized min value
int minI = -1;
int minJ = -1;
int min = 0;
// finding maximal sum among negative sums
while (i < j) {
int cur = a[i] + a[j];
if (cur != 0 && (minI == -1 || Math.abs(cur) < Math.abs(min))) {
min = cur;
minI = i;
minJ = j;
}
// if current sum is below zero, increase it
// by trying the next, larger element
if (cur < 0) {
i++;
} else { // sum is already non-negative, move to the next element
j --;
}
}
i = 0;
j = a.length - 1;
// finding minimal sum among positive sums
while (i < j) {
int cur = a[i] + a[j];
if (cur != 0 && (minI == -1 || Math.abs(cur) < Math.abs(min))) {
min = cur;
minI = i;
minJ = j;
}
if (cur > 0) {
j--;
} else {
i ++;
}
}
if (minI >=0) {
return new Solution(minI, minJ, min);
//System.out.printf("a[%d]=%d, a[%d]=%d, sum=%d", minI, minJ, a[minI], a[minJ], min);
} else {
return null;
//System.out.println("No solution");
}
}
Я просто понял, что сортировка портит показатели, так и minI
minJ
не будет соответствовать показателям в оригинальном, не отсортированном массиве. Исправление прост - исходный массив должен быть преобразован в массив пар (значение, original_index) перед сортировкой. Хотя я не буду реализовывать это исправление в моем фрагменте примера, так как это еще больше повлияет на читаемость.
Какое желаемое поведение при наличии нескольких решений? Просто распечатайте ** ** решение или распечатайте ** al ** l решения? – HyperZ
И как вы пробовали работать? Какой результат вы получаете и какой результат вы ожидаете? – Nanhydrin
Я просто хотел напечатать два элемента из массива, сумма которого ближе к нулю, независимо от знака. – Raheem