Maximum Prefix Subarray Sum — Problem Statement & Solution Guide

ArraysMediumKadane's / Prefix Sum
TimeO(n+|pref|)
|
SpaceO(n)

Quick Answer & Algorithm Key Takeaway

Master coding challenges related to Arrays and solve the Maximum Prefix Subarray Sum problem optimally.

TopicArrays
PatternKadane's / Prefix Sum
TimeO(n+|pref|)
SpaceO(n)

Problem Description

Given an integer array nums and a second integer array pref, determine the largest possible sum of a contiguous subarray of nums that begins with the exact sequence pref. Formally, find an index i such that nums[i..i+|pref|-1] equals pref, then choose an end index j ≥ i+|pref|-1 and compute the sum S = Σ_{k=i}^{j} nums[k]. Among all valid pairs (i, j) return the maximum S. If pref does not appear as a contiguous subsequence of nums, output 0.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Maximum Prefix Subarray Sum"

medium

WHY DOES IT MATTER?

Many real‑world queries ask for the best performance metric that must begin with a known signature (e.g., a transaction log that starts with a specific event). Recognizing the pattern‑first constraint and then optimizing the continuation is a recurring algorithmic motif.

OPTIMIZATION CHALLENGE

The key insight is decoupling the two phases: locate all valid starts in linear time, then pre‑compute the maximum suffix of the prefix‑sum array so each start can instantly retrieve the best possible end. This reduces the naïve O(n·|pref|) or O(n²) to O(n).

REAL-WORLD CONNECTION

Think of a network packet stream where a particular header sequence must be present; once the header is detected, you want to maximize throughput of the following payload. The header detection is pattern matching, and maximizing payload size is analogous to the maximum‑prefix sum.

In an interview, first state the two‑step plan (match then extend), write KMP or rolling hash for the match, then show the suffix‑max trick on prefix sums – this demonstrates both algorithmic breadth and depth.

COMPLEXITY AT A GLANCE

⏱ Time:O(n+|pref|)
💾 Space:O(n)

Core Theory — Why This Approach?

The problem combines pattern matching with a variant of the maximum‑prefix subarray problem. First we must locate every index i where the sub‑array nums[i..i+|pref|-1] exactly equals pref. A naïve scan for each possible i would be O(n·|pref|) and quickly becomes infeasible for large n (up to 10^5 or more). Efficient string‑matching algorithms such as KMP or rolling‑hash (Rabin‑Karp) treat the integer arrays as strings and locate all occurrences in O(n+|pref|) time. Once an occurrence is found, the remaining task is to extend the subarray to the right to maximize its sum while preserving contiguity. This reduces to finding, for each start i, the maximum value of prefixSum[j+1]‑prefixSum[i] for j≥i+|pref|-1, i.e. the maximum suffix of the prefix‑sum array. By pre‑computing the suffix maximum of the prefix‑sum array we can answer each occurrence in O(1), yielding an overall linear solution.

The optimal paradigm therefore intertwines two classic techniques: linear‑time pattern matching to satisfy the prefix constraint, and prefix‑sum + suffix‑maximum preprocessing to answer the “best extension” query instantly. This avoids the quadratic blow‑up of trying every possible end index for every match, which would be O(n²) in the worst case.

Interview Questions on This Problem

Q1How would you modify the solution if the subarray must start with pref but also end with another pattern suf?

First locate all start indices matching pref using KMP, then locate all end indices matching suf. For each start i, find the farthest end index j≥i+|pref|-1 that also begins suf; using a suffix‑maximum array of prefix sums restricted to valid end positions yields the maximum sum in O(n).

Q2What is the time‑space trade‑off if you replace KMP with a hash‑based Rabin‑Karp approach for finding pref?

Rabin‑Karp offers expected O(n) time with O(1) extra space but introduces a small probability of collision, requiring a verification step. KMP guarantees worst‑case O(n) without collisions but uses O(|pref|) extra space for the failure function. Both are linear, but KMP is deterministic.

Examples

Example 1

Input

5
3 -2 5 -1 2
2
3 -2

Output

7

Explanation: The prefix [3,-2] matches the first two elements of nums. Possible subarrays starting there are: [3,-2] → sum = 1 [3,-2,5] → sum = 6 [3,-2,5,-1] → sum = 5 [3,-2,5,-1,2] → sum = 7 The maximum sum is 7.

Example 2

Input

5
1 2 3 4 5
2
2 3

Output

14

Explanation: The prefix [2,3] occurs starting at index 1. Extending the subarray gives: [2,3] → sum = 5 [2,3,4] → sum = 9 [2,3,4,5] → sum = 14 The largest achievable sum is 14.

Example 3

Input

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

Output

-4

Explanation: The prefix [-1,-3] matches nums[1..2]. The subarrays are: [-1,-3] → sum = -4 [-1,-3,-2] → sum = -6 The best (least negative) sum is -4.

Constraints

  • 1 <= nums.length <= 100000
  • 1 <= pref.length <= nums.length
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= pref[i] <= 10^9

Optimal Approach & Strategy

Use KMP (or rolling hash) to find all prefix matches in O(n), compute prefix sums, build a suffix‑max array of those sums, and evaluate each match in O(1).

Brute Force Approach

Check every possible start index, verify the prefix, then try every possible end index to compute the sum, keeping the maximum.

Code Solutions

JavaScript Solution
Time: O(n+|pref|)
// Node.js solution
function maxPrefixSubarraySum(nums, pref) {
    const n = nums.length;
    const m = pref.length;
    if (m === 0) return 0; // empty prefix, any subarray – choose max subarray sum (Kadane) but not required here
    const prefSum = new Array(n + 1).fill(0n);
    for (let i = 0; i < n; ++i) prefSum[i + 1] = prefSum[i] + BigInt(nums[i]);
    const suffixMax = new Array(n + 2).fill(-9223372036854775808n);
    suffixMax[n] = prefSum[n];
    for (let i = n - 1; i >= 0; --i) {
        suffixMax[i] = prefSum[i] > suffixMax[i + 1] ? prefSum[i] : suffixMax[i + 1];
    }
    let best = -9223372036854775808n;
    outer: for (let i = 0; i + m <= n; ++i) {
        for (let k = 0; k < m; ++k) {
            if (nums[i + k] !== pref[k]) continue outer;
        }
        const candidate = suffixMax[i + m] - prefSum[i];
        if (candidate > best) best = candidate;
    }
    if (best === -9223372036854775808n) return 0;
    return Number(best);
}
function main(){
    const fs = require('fs');
    const data = fs.readFileSync(0,'utf8').trim().split(/\s+/).map(Number);
    let p=0;
    const n=data[p++];
    const nums=data.slice(p,p+n); p+=n;
    const m=data[p++];
    const pref=data.slice(p,p+m);
    console.log(maxPrefixSubarraySum(nums,pref).toString());
}
main();

Asked in Top Tech Interviews

OracleAtlassian

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.