Grade 9 · Frequency arrays, prefix sums and the Sieve of EratosthenesCitește în română

Maximum subarray sum (Kadane's algorithm)

Original: Secvența de sumă maximă (algoritmul lui Kadane)

O(n)C++1762 lines2 examples

The idea

We go through the array and keep the sum of the current subarray, which ends at position i. If the sum so far has become negative, it no longer helps: we start a new subarray right at i. After every step we compare the current sum with the best one so far. The maximum sum is printed, then the start and end positions (the first one found). It also works when all numbers are negative.

Original description (Romanian)

Parcurgem vectorul și păstrăm suma secvenței curente, care se termină la poziția i. Dacă suma de până acum a devenit negativă, nu ne mai ajută: începem o secvență nouă chiar de la i. După fiecare pas comparăm suma curentă cu cea mai bună de până acum. Se afișează suma maximă, apoi pozițiile de început și de sfârșit (prima găsită). Funcționează și când toate numerele sunt negative.

Complexity
O(n)
Grade
Grade 9 (Clasa a IX-a)

Examples

Example 1

Input

8
-2 1 -3 4 -1 2 1 -5

Expected output

6
4 7
Example 2

Input

3
-5 -2 -8

Expected output

-2
2 2

The code

Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.

secventa-de-suma-maxima.cpp
/*
 * Titlu: Secvența de sumă maximă (algoritmul lui Kadane)
 * Clasa: 9
 * Capitol: Frecvență, sume parțiale și ciurul lui Eratostene
 * Descriere: Parcurgem vectorul și păstrăm suma secvenței curente, care se
 *            termină la poziția i. Dacă suma de până acum a devenit negativă, nu
 *            ne mai ajută: începem o secvență nouă chiar de la i. După fiecare
 *            pas comparăm suma curentă cu cea mai bună de până acum. Se afișează
 *            suma maximă, apoi pozițiile de început și de sfârșit (prima găsită).
 *            Funcționează și când toate numerele sunt negative.
 * Complexitate: O(n)
 *
 * Exemplu
 * Intrare:
 * 8
 * -2 1 -3 4 -1 2 1 -5
 * Ieșire:
 * 6
 * 4 7
 *
 * Exemplu
 * Intrare:
 * 3
 * -5 -2 -8
 * Ieșire:
 * -2
 * 2 2
 */
#include <iostream>
using namespace std;

int v[100001];

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i];
    }
    long long suma = 0, sumaMax = v[1];
    int inceput = 1, stMax = 1, drMax = 1;
    for (int i = 1; i <= n; i++)
    {
        if (suma < 0)
        {
            suma = 0;
            inceput = i;
        }
        suma = suma + v[i];
        if (suma > sumaMax)
        {
            sumaMax = suma;
            stMax = inceput;
            drMax = i;
        }
    }
    cout << sumaMax << '\n' << stMax << ' ' << drMax << '\n';
    return 0;
}

Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.