Skip to main content

Partition Array for Maximum Sum

Problem Statement:​

Given an integer arrayΒ arr, partition the array into (contiguous) subarrays of lengthΒ at mostΒ k. After partitioning, each subarray has their values changed to become the maximum value of that subarray.

ReturnΒ the largest sum of the given array after partitioning. Test cases are generated so that the answer fits in aΒ 32-bitΒ integer.

  • Example:

    Example 1:

    Input: arr = [1,15,7,9,2,5,10], k = 3
    Output: 84
    Explanation: arr becomes [15,15,15,9,10,10,10]
    Example 2:

    Input: arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
    Output: 83
    Example 3:

    Input: arr = [1], k = 1
    Output: 1


βœ… Solution: Memoization​

class Solution {
public:
// Recursive helper to compute max sum starting from index i
int solve(int i, int n, int k, vector<int> &arr, vector<int> &dp){
if(i == n) return 0;
if(dp[i] != -1) return dp[i];

int len = 0;
int maxi = INT_MIN;
int maxans = INT_MIN;

// Try all partitions of length up to k
for(int j = i; j < min(i + k, n); j++){
len++;
maxi = max(maxi, arr[j]); // Keep track of max in this partition

// Compute cost: max * len + solve remaining part
int ans = maxi * len + solve(j + 1, n, k, arr, dp);
maxans = max(maxans, ans); // Maximize result
}

return dp[i] = maxans;
}

int maxSumAfterPartitioning(vector<int>& arr, int k) {
int n = arr.size();
vector<int> dp(n + 1, -1); // dp[i] = max sum from index i to end
return solve(0, n, k, arr, dp);
}
};


βœ… Solution: Tabulation​

class Solution {
public:
int maxSumAfterPartitioning(vector<int>& arr, int k) {
int n = arr.size();
vector<int> dp(n + 1, 0); // dp[i] = max sum starting from i

// Fill dp array from end to start
for(int i = n - 1; i >= 0; i--){
int len = 0;
int maxi = INT_MIN;
int maxans = INT_MIN;

for(int j = i; j < min(i + k, n); j++){
len++;
maxi = max(maxi, arr[j]);
int ans = maxi * len + dp[j + 1];
maxans = max(ans, maxans);
}

dp[i] = maxans;
}

return dp[0];
}
};


πŸ“ How It Works​

  • We are allowed to partition the array into blocks of size at most k.

  • For each block, we calculate its cost as:

    max in block * size of block.

  • We then recurse or build the DP table to compute the maximum sum possible after choosing all partitions optimally.

  • dp[i] stores the maximum sum we can achieve starting from index i.


🧩 Key Formula / Transition​

dp[i] = max(
max(arr[i..j]) * (j - i + 1) + dp[j + 1]
) for all j in [i, i+k-1]


⏱️ Time & Space Complexity​

ApproachTimeSpace
MemoizationO(N*K)O(N)
TabulationO(N*K)O(N)
  • We explore up to k elements from each index i.

⚠️ Edge Cases​

  • k = 1 β†’ Only 1-element partitions.
  • All elements are the same β†’ Partition into max k size to get max sum.
  • k >= n β†’ Can take the whole array as a single partition.

πŸ’‘ Other Approaches​

ApproachTimeComment
Recursive OnlyExponential ❌Too slow
MemoizationO(N*K) βœ…Top-down
TabulationO(N*K) βœ…Bottom-up


πŸš€ Level Up Your Engineering Mindset

Never Study in Isolation. Join Binary Dose.

Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚑
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

πŸ’‘Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→