Maximum Score of a Good Subarray

Updated on 11 June, 2025
Maximum Score of a Good Subarray header image

Problem Statement

In this problem, we are provided with an array of integers nums and an integer k. Our goal is to determine the maximum score possible from a specific subarray of the list nums. The subarray needs to include the position k (hence, i ≤ k ≤ j where i is the starting index and j is the ending index of the subarray).

The score of any given subarray (i, j) is determined by the product of the smallest number in the subarray (min(nums[i], nums[i+1], ..., nums[j])) and the length of the subarray ((j - i + 1)). The challenge here is to ensure we select a subarray which both includes the position k and maximizes the resulting score based on the defined criteria.

Examples

Example 1

Input:

nums = [1,4,3,7,4,5], k = 3

Output:

15

Explanation:

The optimal subarray is (1, 5) with a score of min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15.

Example 2

Input:

nums = [5,5,4,5,4,1,1,1], k = 0

Output:

20

Explanation:

The optimal subarray is (0, 4) with a score of min(5,5,4,5,4) * (4-0+1) = 4 * 5 = 20.

Constraints

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 2 * 104
  • 0 <= k < nums.length

Approach and Intuition

  1. To maximize the score of a good subarray that includes index k, we must find bounds i and j (end points of the subarray) so that:

    • k falls within indices i and j.
    • The score calculated using the minimum value in this range and the subarray length is maximized.
  2. Start by considering the element at the kth index because it must be included in all potential subarrays. From this point, expand outwards in both directions:

    • Expand to the left while the potential of increasing the score is present (i.e., taking larger elements if possible).
    • Expand to the right under the same conditions.
  3. While expanding, keep track of the smallest value encountered since this will determine the score for any subarray configuration with the current limits (i, j). Multiply this minimum value by the current span of the subarray to compute the potential score.

  4. Maintain the maximum score seen during this expansion process. To do this, adjust i and j to include larger values that still ensure the subarray is a good subarray, and check if the score from this new configuration is higher than your current maximum score.

  5. The process above will involve iterating through the array potentially multiple times (specifically moving back and forth relative to k), but deducing the underlying structure and adjusting the limits while maintaining the validation condition i ≤ k ≤ j is key.

Through these steps, it is possible to compute the maximum score for a good subarray in a way that smartly and efficiently explores potential subarray configurations, always making sure to maximize the score based on the minimal element present and the breadth of the subarray.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int maxScore(vector<int>& elements, int targetIndex) {
        int count = elements.size();
        int begin = targetIndex;
        int end = targetIndex;
        int best = elements[targetIndex];
        int minimumValue = elements[targetIndex];
        
        while (begin > 0 || end < count - 1) {
            if ((begin > 0 ? elements[begin - 1] : 0) < (end < count - 1 ? elements[end + 1] : 0)) {
                end++;
                minimumValue = min(minimumValue, elements[end]);
            } else {
                begin--;
                minimumValue = min(minimumValue, elements[begin]);
            }
            
            best = max(best, minimumValue * (end - begin + 1));
        }
        
        return best;
    }
};

The solution provided in C++ aims to find the maximum score of a "good" subarray from an array of integers, using a specific index as a starting point. The main goal is to compute the area under the minimum element within the subarray expanding around the given target index. Here’s a breakdown of how the solution is implemented:

  • Initialize indices begin and end to targetIndex. Start with the targeted element and then expand outwards to determine the largest possible score for subarrays containing the initial target.
  • The initial best score is set to the value at targetIndex. Also, initialize minimumValue to this value, which tracks the minimum in the current subarray.
  • Expand the subarray boundaries by comparing values on both sides of the begin and end. The extension is determined by whether the next element outside of the current boundary has a higher value compared to the other side or if one side has already reached the boundary of the array.
  • If expanding right if safe and beneficial (i.e., the value next to end when it hasn't reached the rightmost boundary), increase end. Otherwise, decrement begin, unless it's already at the leftmost boundary.
  • The minimumValue is updated to be the lower between the current minimumValue and the new edge element included in the subarray by either incrementing end or decrementing begin.
  • Update best to be the maximum between the current best and the product of minimumValue and the current subarray length (end - begin + 1).
  • Continue expanding begin and end until one of them cannot extend any further without going out of the array bounds.
  • The function ultimately returns the highest calculated best score.

This algorithm efficiently finds the maximum score by optimally expanding around the center index and updating the conditions based on local comparisons, making it a robust solution for the problem of determining the maximum score of a subarray based around a starting index.

java
class Solution {
    public int findMaxScore(int[] arr, int pivot) {
        int size = arr.length;
        int i = pivot;
        int j = pivot;
        int maxScore = arr[pivot];
        int minimum = arr[pivot];

        while (i > 0 || j < size - 1) {
            if ((i > 0 ? arr[i - 1] : 0) < (j < size - 1 ? arr[j + 1] : 0)) {
                j++;
                minimum = Math.min(minimum, arr[j]);
            } else {
                i--;
                minimum = Math.min(minimum, arr[i]);
            }

            maxScore = Math.max(maxScore, minimum * (j - i + 1));
        }

        return maxScore;
    }
}

This program in Java aims to find the maximum score of a good subarray with a specified pivot. The score of the subarray is determined by the product of the minimum value in the subarray and its length. The function findMaxScore receives an integer array arr and an integer pivot as arguments.

  • Start by initializing two pointers, i and j, at the pivot index, and the maxScore is initialized to the value at the pivot.
  • The variable minimum keeps track of the smallest value within the bounds defined by i and j.
  • Use a while loop to expand the subarray outward from the pivot as long as i is greater than 0 or j is less than the size of the array minus one.
  • In each iteration of the loop, compare the elements just outside the current bounds of the subarray and expand towards the larger value.
  • Update the minimum variable to the lesser value between the current minimum and the new edge value of the subarray.
  • Calculate the score for the current subarray and update maxScore if the current score is higher.

This solution effectively evaluates all possible subarrays that include the pivot element to locate the one with the maximum score based on the defined criteria. The use of two pointers maximizes efficiency by expanding the search space strategically based on potential gains from both ends of the subarray.

python
class Solution:
    def maxScoreInInterval(self, values: List[int], index: int) -> int:
        length = len(values)
        l_ptr = index
        r_ptr = index
        max_score = values[index]
        temp_min = values[index]
        
        while l_ptr > 0 or r_ptr < length - 1:
            if (values[l_ptr - 1] if l_ptr else 0) < (values[r_ptr + 1] if r_ptr < length - 1 else 0):
                r_ptr += 1
                temp_min = min(temp_min, values[r_ptr])
            else:
                l_ptr -= 1
                temp_min = min(temp_min, values[l_ptr])

            max_score = max(max_score, temp_min * (r_ptr - l_ptr + 1))
        
        return max_score

The provided Python solution addresses the problem of finding the maximum score from a good subarray. This score is determined by first identifying the minimum value within a given interval and then multiplying it by the number of elements in that interval. Here's a summary of how this solution functions:

  • Start with setting both left and right pointers at the given index, and initially set the maximum score to the value at this index.
  • The while loop continues to expand until either of the pointers can no longer extend without going out of array bounds.
  • In each iteration:
    • Compare the element just outside the left bound with the element just outside the right bound.
    • If the right side element is greater, shift the right pointer one step further, update the minimum value for the current subarray, and calculate the potential new maximum score.
    • If the left side element is greater or if you're at the end of the array on the right, shift the left pointer one step backwards, again update the minimum, and check for a new maximum score.
  • Continue expanding the window and updating scores until both pointers are either at the start or end of the list, respectively.
  • Return the computed maximum score after all possible expansions are checked.

This approach ensures that for each possible good subarray (by moving outward from the initial index), the algorithm efficiently finds the maximum score achievable. The use of pointers and the minimum tracking within the while loop helps in optimizing the computations needed as it reduces unnecessary recalculations.

Comments

No comments yet.