Может быть, это метод грубой силы, который вы уже пробовали, но я думаю, что это самый простой способ.
Начиная с подмножества первых двух элементов, повторяем подмножества увеличение размера, сравнивая сумму значений каждого элемента в подмножестве и значения последнего элемента. Когда вы найдете сумму в пределах диапазона, все готово.
Это позволит найти первую пару чисел в пределах диапазона на основе определения «первым» будет «пара с наименьшим максимальным индексом».
function findFirstSumInRange(int $min, int $max, array $values = []): array
{
for ($b = 1, $n = count($values); $b < $n; $b++) {
for ($a = 0; $a < $b; $a++) {
if ($min <= ($sum = $values[$a] + $values[$b]) && $sum <= $max) {
return [$values[$a], $values[$b]];
// or return [$a => $values[$a], $b => $values[$b]]; if you need the keys as well
}
}
}
return [];
}
Вы можете сделать это быстрее, пропустив любые значения, которые уже превышают верхнюю границу диапазона.
function findFirstSumInRangeB(int $min, int $max, array $values = []): array
{
for ($b = 1, $n = count($values); $b < $n; $b++) {
if ($values[$b] < $max) { // else these sums will all be > the range because one addend is
for ($a = 0; $a < $b; $a++) {
if ($values[$a] < $max && $min <= ($sum = $values[$a] + $values[$b]) && $sum <= $max) {
return [$a => $values[$a], $b => $values[$b]];
}
}
}
}
return [];
}
Что касается "наиболее эффективного решения", я бы предпочитайте go для простоты, а не для оптимизации производительности, если производительность не вызывает проблем. Просто мое мнение.