Medium–hard · one pass, one idea

Maximum Subarray Sum

Out of all the contiguous stretches of the array, which one has the biggest sum? The brute force is O(n²). The insight is one sentence long.

At a glanceKadane's algorithm — running = max(a[i], running + a[i]) and best = max(best, running); it stays correct on all-negative arrays because the stretch must be non-empty.

Problem

Input: The first line is an integer n (1 ≤ n ≤ 1000). The second line holds n integers separated by spaces (−1000 ≤ ai ≤ 1000). The numbers may be negative.

Output: The largest possible sum of a non-empty contiguous stretch.

Samples:

InputOutput
8
-2 1 -3 4 -1 2 1 -5
6
5
-3 -1 -7 -2 -5
-1
1
5
5

In the first sample the best stretch is 4 -1 2 1 = 6. In the second, every number is negative, so you must still pick one — the answer is −1, not 0. That case is where most solutions break.

Your solution

main.cpp — your solution
Custom input for "Run my input"

Judging runs in your browser against hidden tests. A runaway loop is cut off after 3 seconds — still, make sure every loop has an exit. Your code is saved in this browser as you type.

Stuck? Hints

Hint 1 — The brute force first, so you can feel the waste

Try every start i, every end j, sum the range, keep the max. That's O(n²) — for n = 1000 it's about a million additions, and most of them are recomputing sums you already had. The fast solution never looks backwards.

Hint 2 — One running total is enough

Keep cur = the best sum of a stretch ending at the current position. When the next number x arrives you have exactly two choices: extend the run (cur + x) or start a new run at x. Take the larger. Then update best if cur beat it.

Hint 3 — The one-sentence insight

If cur is negative, it can only drag the next number down — so throw it away and start fresh. That's it: if (cur < 0) cur = x; else cur = cur + x;. Everything else is bookkeeping.

Solution (try it first!)
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int best, cur;
    cin >> best;
    cur = best;
    for (int i = 1; i < n; i++) {
        int x;
        cin >> x;
        if (cur < 0) cur = x;
        else cur = cur + x;
        if (cur > best) best = cur;
    }
    cout << best << endl;
    return 0;
}

This is Kadane's algorithm, and it's the standard introduction to dynamic programming: cur is a state that summarises everything you need to know about the past in one number. You didn't remember the array — you remembered the one thing that matters. That reframing, "what is the minimum I must carry forward?", is the entire discipline. And it's the last problem in the chain — you've now covered input, loops, arrays, strings, bits, sorting, searching and one real algorithm. Go back through the list and see how many you can do without hints.

Deep dive

Why this works

Keep cur = the best sum of a stretch ending right here. When the next number arrives you have two choices: extend the run, or start a new one at it. Take the larger.

The cost

O(n) in one pass with two extra variables. Enumerating every range is O(n²) — and most of those additions recompute sums you already had.

Where it goes wrong

  • Starting best at 0 prints 0 for all-negative input, but the empty stretch is not allowed — the answer is the largest negative number.
  • Deciding with if (x > 0) instead of if (cur < 0) extends a negative run that should have been abandoned, and the maximum comes out too low.

Next step

That's the end of the chain. Look back at the first problem — you have come a long way.

Two things to remember

  • A negative running total only drags you down — drop it and restart at the current number.
  • The core question of dynamic programming: what is the least I must carry forward?
🐞 This version fails — open it and try

best starts at 0 — all-negative input gives 0, but the empty stretch is not allowed

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int best = 0, cur = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (cur < 0) cur = x;
        else cur = cur + x;
        if (cur > best) best = cur;
    }
    cout << best << endl;
    return 0;
}