оптимальный алгоритм
Есть задачка: найти наибольшую сумму непрерывного подмассива в массиве.
Массив называется непрерывным, когда индексы его элементов следеют друг за другом ([5]=>1,[6]=>2,[7]=>3).
Например: массив (1,2,3,-4,5) - наибольшая непрерывная сумма подмассива равна 7 (сумма всех элементов массива). Для массива (1,2,3,-40,5) эта сумма будет равна 5 (сумма первых трех)
Итак, алгоритм:
Слишком тупой:
for ($i=0;$i<count($inputArray);$i++) {
for ($ii=count($inputArray);$ii>0;$ii--) {
$sum = 0;
for ($iii=$i;$iii<$ii-$i;$iii++) {
$sum += $inputArray[$iii];
}
if ($sum>$maxSum)
$maxSum = $sum;
}
}
for ($i=0;$i<count($inputArray);$i++) {
if (($inputArray[$i]>0) || check($i))
$maxSum += $inputArray[$i];
else
break;
}
echo $maxSum;
function check($p) {
global $inputArray;
$sum = 0;
for ($i=$p+1;$i<count($inputArray);$i++) {
if (($inputArray[$i]>0) || check($i))
$sum += $inputArray[$i];
else
return false;
}
if (abs($inputArray[$p])<$sum)
return true
else
return false;
}
$sum = null;
$n = false;
$negVal = 0;
for ($i=0;$i<count($inputArray);$i++) {
if ($inputArray[$i]>0) {
$sum += $inputArray[$i];
if ($n && ($sum>0)) {
$n = false;
$sum = $maxSum + $sum;
}
}
else {
if (!is_numeric($sum)) {
if ($i==0 || ($negVal< $inputArray[$i]))
$negVal = $inputArray[$i];
}
else {
if (!$n) {
$n = true;
$maxSum = $sum;
$sum = $inputArray[$i];
}
else
$sum += $inputArray[$i];
}
}
echo $sum."\r\n";
}
if (!is_numeric($sum))
$maxSum = $negVal;
elseif ($maxSum<$sum)
$maxSum = $sum;
echo $maxSum;
Это, если мы учитываем непрерывные пустые подмассивы. В этом случае максимальная сумма 0, если все элементы массива отрицательные, иначе равна максимальной из сумм последовательных неотрицательных элементов.
$curSum = 0;
for ( $inputArray as $elem ) {
if ( $elem >= 0 ) {
$curSum += $elem;
} else {
if ( $curSum > $maxSum ) {
$maxSum = $curSum;
}
$curSum = 0;
}
}
Это, если мы не учитываем пустые непрерывные подмассивы. В этом случае сумма равна максимальному элементу, если все элементы отрицательны, иначе равна максимальной из сумм последовательных неотрицательных элементов.
$curSum = null;
for ( $inputArray as $elem ) {
if ( $elem >= 0 ) {
if ( !is_numeric( $curSum ) ) {
$curSum += $elem;
} else {
$curSum = $elem;
}
} else {
if ( !is_numeric( $maxSum ) || $elem > $maxSum ) {
$maxSum = $elem;
}
if ( is_numeric( $curSum ) && $curSum > $maxSum ) {
$maxSum = $curSum;
}
$curSum = null;
}
}
По асимптотике быстрее, чем O(n) здесь ничего быть не может. Величина константы - вопрос открытый, но думаю, что что-то намного быстрее придумать сложно.
Массив называется непрерывным, когда индексы его элементов следеют друг за другом ([5]=>1,[6]=>2,[7]=>3).
Например: массив (1,2,3,-4,5) - наибольшая непрерывная сумма подмассива равна 7 (сумма всех элементов массива). Для массива (1,2,3,-40,5) эта сумма будет равна 5 (сумма первых трех)
Кстати, это задача на динамическое программирование (сродни дискретной задаче об укладке рюкзака), нужно кэшировать промежуточные суммы, возможно вечерком предложу свое решение. И еще. Вы путаете терминологию. В вашем случае, это не массивы, это таблицы (хэш-таблицы), так как массив подразумевает участок памяти с последовательным расположением элементов, где каждый элемент имеет индекс - номер своей позиции.
Я так понял суть задачи - найти такие последовательные элементы массива, сумма которых была бы максимальной (сумма никаких других последовательных элементов не была бы больше найденной). Верно?
Сам не знал, что сумма не может быть отрицательной...
А как насчет массива (-1,-2,-3,-4,-5) ???
А как насчет по ссылке сходить?!
"Given an array of integers, find a subarray which maximizes the sum of its elements, that is, the elements of no other single subarray add up to a value larger than this one. An empty subarray is considered to have the sum 0; thus if all elements are negative, the result must be the empty sequence."
Ээээ! Не грубить! При чем тут ссылка и изначально поставленное вами условие задачи?!
ПыСы. По ссылке все еще "иду". В процессе я..
Сам не знал, что сумма не может быть отрицательной...
больше всего мне понравилась реализация на языке J...
Т.е. вы хотите сказать, что операция суммирования не определена на отрицательных числах и сумма (какой кошмар) не может быть отрицательным числом?
Если это ко мне, то я ничего такого сказать не хочу :) Совсем наоборот!
Если сумма отрицательная, значит вертаем 0. ;)