Taro Logo

Partition Array for Maximum Sum

Medium
Google logo
Google
Topics:
ArraysDynamic Programming

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.

For example:

Consider the array arr = [1,15,7,9,2,5,10] and k = 3. The optimal partitioning would be [15,15,15,9,10,10,10]. The sum is 15 + 15 + 15 + 9 + 10 + 10 + 10 = 84. Therefore, the function should return 84.

Another example, if arr = [1,4,1,5,7,3,6,1,9,9,3] and k = 4, what is the maximum sum after partitioning?

Could you write a function to solve this problem efficiently?

Solution


Let's analyze the problem. We are given an array and an integer k. We need to partition the array into subarrays of length at most k. After partitioning, each subarray will have all its values changed to the maximum value of that subarray. We need to find the largest possible sum of the array after this partitioning.

Brute Force Solution

A brute force solution involves trying out all possible partitions of the array into subarrays of length at most k. For each partition, we calculate the sum of the modified array and keep track of the maximum sum seen so far.

The algorithm works as follows:

  1. Iterate through all possible starting positions for the first subarray.
  2. For each starting position, iterate through all possible lengths of the first subarray (up to k).
  3. Recursively solve the problem for the remaining part of the array.
  4. Calculate the sum of the modified array for the current partition.
  5. Update the maximum sum seen so far.

This approach has exponential time complexity, as it explores all possible partitions.

Big O Analysis

  • Time Complexity: O(k^n) where n is the length of array and k is the maximum subarray size. Because for each element, we can choose subarrays of length atmost k.
  • Space Complexity: O(n) due to the recursive call stack.

Optimal Solution: Dynamic Programming

We can optimize the solution using dynamic programming. We can define dp[i] as the largest sum achievable for the first i elements of the array.

The recurrence relation is as follows:

dp[i] = max(dp[i-j] + max_val * j) for all 1 <= j <= k

where max_val is the maximum value in the subarray arr[i-j+1...i].

Algorithm:

  1. Create a dp array of size n+1 initialized with 0.
  2. Iterate through the array from i = 1 to n.
  3. For each i, iterate through all possible lengths j from 1 to k.
  4. Calculate the maximum value in the subarray arr[i-j...i-1].
  5. Update dp[i] using the recurrence relation: dp[i] = max(dp[i], dp[i-j] + max_val * j).
  6. Return dp[n].

Edge Cases:

  • When the array is empty, the largest sum is 0.
  • When k is 1, the largest sum is the sum of the original array.
  • When k is greater than or equal to the length of the array, the largest sum is the length of the array multiplied by the maximum element of the array.

Example:

Consider arr = [1,15,7,9,2,5,10] and k = 3.

  1. dp[0] = 0
  2. i = 1: dp[1] = max(dp[0] + 1 * 1) = 1
  3. i = 2: dp[2] = max(dp[1] + 15 * 1, dp[0] + 15 * 2) = max(16, 30) = 30
  4. i = 3: dp[3] = max(dp[2] + 7 * 1, dp[1] + 15 * 2, dp[0] + 15 * 3) = max(37, 31, 45) = 45
  5. i = 4: dp[4] = max(dp[3] + 9 * 1, dp[2] + 9 * 2, dp[1] + 15 * 3) = max(54, 48, 46) = 54
  6. i = 5: dp[5] = max(dp[4] + 2 * 1, dp[3] + 9 * 2, dp[2] + 9 * 3) = max(56, 63, 57) = 63
  7. i = 6: dp[6] = max(dp[5] + 5 * 1, dp[4] + 5 * 2, dp[3] + 9 * 3) = max(68, 64, 72) = 72
  8. i = 7: dp[7] = max(dp[6] + 10 * 1, dp[5] + 10 * 2, dp[4] + 10 * 3) = max(82, 83, 84) = 84

The final answer is 84.

def maxSumAfterPartitioning(arr, k):
    n = len(arr)
    dp = [0] * (n + 1)
    for i in range(1, n + 1):
        max_val = 0
        for j in range(1, min(k, i) + 1):
            max_val = max(max_val, arr[i - j])
            dp[i] = max(dp[i], dp[i - j] + max_val * j)
    return dp[n]

Big O Analysis

  • Time Complexity: O(n*k), where n is the length of the array and k is the maximum subarray size.
  • Space Complexity: O(n), for storing the dp array.