2015-01-22 2 views
1

Существует массив целых чисел (как положительных, так и отрицательных). Пожалуйста, советьте алгоритм, который даст вам подмассиву с максимальной суммой. Пример:Алгоритм извлечения подмассива из целочисленного массива, который содержит максимальное суммирование

int a[] = new int[]{2,3,-1,4,5,7,8,13,-20}; 

, то ответ должен быть {4,5,7,8,13}, как 4 + 5 + 7 + 8 + 13 = 37.

Я не могу разработать алгоритм для этой проблемы.

+0

Вы пытаетесь Подмножество из определенного количества номеров? –

+1

Без дополнительных ограничений это тривиально. Просто добавьте все положительные элементы массива. Если нет положительных значений, сумма равна 0 (пустое подмножество) или единому максимальному элементу (1 элемент подмножества) в зависимости от требований. Но в этом случае непонятно, почему {2, 3} исключены из результата. Может быть, вы имеете в виду подпоследовательность ** упорядоченного массива? – Jarlax

+0

Jarlax: Assum of {2,3} равен 5. Но сумма {4,5,7,8,13} равна 37 и 37> 5. –

ответ

-1
var a = [2,3,-1,4,5,7,8,13,-20]; 
var positiveNums = a.filter(function(num){ 
    return num > 0 
}); // [2,3,4,5,7,8,13] 
var sum = positiveNums.reduce(function(a, b){ 
    return a+b; 
}); // 42 
+0

Наверняка ваша функция' cut' вернется к 'true' или' false' ??? – RiggsFolly

+0

cut не функция это массив мой плохой возможно это исправление будет лучше @RiggsFolly –

4

Вот линейное решение этой проблемы:

long getMaximumSubarraySum(int[] a) { 
    int start = 0; 
    int end = 0; 
    long result = 0; // I assume that an empty subarray is allowed. 
    long minPrefixSum = 0; 
    int minPrefixSumPos = -1; 
    long currentPrefixSum = 0; 
    for (int i = 0; i < a.length; i++) { 
     currentPrefixSum += a[i]; 
     if (currentPrefixSum - minPrefixSum > result) { 
      result = currentPrefixSum - minPrefixSum; 
      start = minPrefixSumPos + 1; 
      end = i + 1; 
     } 
     if (currentPrefixSum < minPrefixSum) { 
      minPrefixSum = currentPrefixSum; 
      minPrefixSumPos = i; 
     } 
    } 
    // The resulting subarray is [start; end). 
    return result; 
} 

Идея этого алгоритма очень проста: давайте посмотрим на префикс сумм. Тогда ответ будет максимальным значением max(prefixSum[i] - prefixSum[j]), где j < i для всех i. Это именно то, что делает этот код: он выполняет итерацию по входному массиву, поддерживает текущую префиксную сумму и минимальную сумму префикса и выбирает лучший ответ.

+0

Небольшие комментарии. Вопрос заключался в том, как получить сам суб-массив, а не сумму. Кроме того, ваш код позволяет использовать подмассивы с нулевой длиной (что может быть или не быть приемлемым). – Jarlax

+1

@Jarlax Я изменил код так, чтобы он также нашел сам субараб. Субарах с нулевой длиной выглядит естественным, потому что в противном случае возникает вопрос: что делать, если 'a' пуст? – kraskevich

+0

thanks @ILoveCoding –

0

Несколько месяцев назад я решил эту проблему, поэтому я собираюсь предоставить вам алго. Вы должны написать программу.

Основной момент программы заключается в том, что сумма уменьшается, когда вы сталкиваетесь с числовым числом в массиве. Поэтому, когда это произойдет, вы разделите массив на 3 части.
1) Сумма до сих пор
2) Сумма до сих пор + в negetive значение (или значения, если есть непрерывные negetive числа)
3) (2) + сумма, пока вы столкнетесь еще negetive номер

Учитывая эти 3 части, выберите часть с максимальным значением и сохраните ее в переменной. Это значение становится (1) для следующей итерации. Продолжайте, пока вы дойдете до конца массива

Вот псевдо-код:

do until end of array{ 
     b=compute_b() //Compute sum till you encounter negetive number 
     c=compute_c() //Compute sum till you encounter a positive number 
     a=max+b+c; 
     if(a>c) 
     { 
      if(a>max) 
      { 
         max=a; 
      } 
     } 
     else 
     { 
       if(c>max) 
       { 
        max=c; 
       } 
      } 
    } 
    print max 
Смежные вопросы