Facebook Pixel

3496. Maximize Score After Pair Deletions πŸ”’

Problem Description

You have an array of integers nums. You need to perform operations on this array until only one or two elements remain.

In each operation, you can choose one of three actions:

  • Remove the first two elements from the array
  • Remove the last two elements from the array
  • Remove the first element and the last element from the array

Each time you perform an operation, you add the sum of the removed elements to your total score.

The goal is to find the maximum possible total score you can achieve through these operations.

For example, if you have nums = [1, 2, 3, 4], you could:

  • Remove first and last (1 + 4 = 5), leaving [2, 3]
  • Then remove the remaining two (2 + 3 = 5)
  • Total score = 5 + 5 = 10

The key insight is that since we're always removing elements from the endpoints (either both from one end or one from each end), the elements that remain at the end will be either:

  • One element (if the array has odd length)
  • Two consecutive elements (if the array has even length)

To maximize the score, we want to maximize the sum of removed elements, which means minimizing what remains. So for odd-length arrays, we minimize by keeping the smallest single element. For even-length arrays, we minimize by keeping the pair of consecutive elements with the smallest sum.

The solution calculates the total sum s of all elements, then subtracts either the minimum element (for odd length) or the minimum sum of consecutive pairs (for even length) to get the maximum score.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key observation is to think about what remains after all operations, rather than what we remove. Since every operation removes elements from the endpoints (either both from one side or one from each side), we're essentially "peeling away" the array from the outside.

Let's trace through what happens:

  • Each operation removes exactly 2 elements
  • We always remove from the endpoints (first two, last two, or first and last)
  • This continues until we can't perform any more operations

When can we no longer perform operations? When we have 1 or 2 elements left. Since each operation removes 2 elements:

  • If n is odd, we'll have 1 element remaining after (n-1)/2 operations
  • If n is even, we'll have 2 elements remaining after (n-2)/2 operations

Now comes the crucial insight: which elements can possibly remain?

Since we're always removing from endpoints, imagine the array as being "protected" by layers. The elements that survive longest are those in the "center" of these removal operations. For an even-length array, the final two elements must be consecutive in the original array - we can't skip over elements because we only remove from endpoints.

For example, with [a, b, c, d], we could end up with:

  • [b, c] by removing first and last, then first and last again
  • [a, b] by removing last two, then last two
  • [c, d] by removing first two, then first two

But we could never end up with [a, c] or [b, d] because they're not consecutive.

Since our score is the sum of all removed elements, and the total sum is fixed, maximizing the score means minimizing what remains. Therefore:

  • For odd n: find the minimum single element
  • For even n: find the minimum sum of any two consecutive elements

This transforms the problem from a complex dynamic programming question about removal sequences into a simple linear scan for minimum values.

Learn more about Greedy patterns.

Solution Approach

The implementation follows directly from our intuition using a reverse thinking approach:

  1. Calculate the total sum: First, we compute s = sum(nums) to get the sum of all elements in the array.

  2. Check array length parity: We use len(nums) & 1 to check if the length is odd. This bitwise AND operation with 1 returns 1 for odd numbers and 0 for even numbers.

  3. Handle odd-length arrays:

    • If the array has odd length, exactly one element will remain
    • We want to minimize this remaining element to maximize our score
    • Return s - min(nums), which gives us the maximum possible score
  4. Handle even-length arrays:

    • If the array has even length, exactly two consecutive elements will remain
    • We need to find the minimum sum of any two consecutive elements
    • Use pairwise(nums) to iterate through consecutive pairs (a, b)
    • The pairwise function generates pairs like (nums[0], nums[1]), (nums[1], nums[2]), etc.
    • Calculate a + b for each pair and find the minimum
    • Return s - min(a + b for a, b in pairwise(nums))

The algorithm has a time complexity of O(n) where n is the length of the array, as we iterate through the array once to calculate the sum and once more to find either the minimum element or minimum consecutive pair sum. The space complexity is O(1) as we only use a constant amount of extra space.

This elegant solution transforms what appears to be a complex dynamic programming problem into a simple linear scan by recognizing that we only need to identify what remains rather than tracking the entire sequence of removals.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [3, 1, 5, 2, 4].

Step 1: Calculate total sum

  • s = 3 + 1 + 5 + 2 + 4 = 15

Step 2: Check array length

  • Length is 5, which is odd
  • This means after all operations, exactly 1 element will remain

Step 3: Determine what can remain Since we always remove from endpoints, let's see which single elements could possibly remain:

  • Could keep 3: Remove (1,4), then (5,2) β†’ Score = 5 + 7 = 12
  • Could keep 1: Remove (3,4), then (5,2) β†’ Score = 7 + 7 = 14
  • Could keep 5: Remove (3,4), then (1,2) β†’ Score = 7 + 3 = 10
  • Could keep 2: Remove (3,5), then (1,4) β†’ Score = 8 + 5 = 13
  • Could keep 4: Remove (3,5), then (1,2) β†’ Score = 8 + 3 = 11

Notice that in each case: Score = Total Sum - Remaining Element = 15 - remaining

Step 4: Maximize score by minimizing what remains

  • The minimum element is min(nums) = 1
  • Maximum score = 15 - 1 = 14

Let's verify with another example where the array has even length: nums = [2, 3, 1, 4].

Step 1: Calculate total sum

  • s = 2 + 3 + 1 + 4 = 10

Step 2: Check array length

  • Length is 4, which is even
  • This means exactly 2 consecutive elements will remain

Step 3: Find all possible consecutive pairs

  • Pair [2,3]: sum = 5
  • Pair [3,1]: sum = 4
  • Pair [1,4]: sum = 5

Step 4: Maximize score

  • Minimum consecutive pair sum = 4 (the pair [3,1])
  • Maximum score = 10 - 4 = 6

To verify: if we keep [3,1], we remove (2,4) with score = 6, which matches our calculation.

Solution Implementation

1from typing import List
2from itertools import pairwise
3
4class Solution:
5    def maxScore(self, nums: List[int]) -> int:
6        # Calculate the total sum of all numbers
7        total_sum = sum(nums)
8      
9        # Check if the length of nums is odd
10        if len(nums) & 1:  # Bitwise AND with 1 checks if odd
11            # If odd length, remove the minimum single element
12            return total_sum - min(nums)
13      
14        # If even length, find the minimum sum of consecutive pairs
15        # and remove that pair to maximize the remaining score
16        min_pair_sum = min(a + b for a, b in pairwise(nums))
17        return total_sum - min_pair_sum
18
1class Solution {
2    public int maxScore(int[] nums) {
3        // Constants
4        final int INFINITY = 1 << 30;  // Large value representing infinity (2^30)
5      
6        // Initialize variables
7        int arrayLength = nums.length;
8        int totalSum = 0;
9        int minSingleElement = INFINITY;
10        int minAdjacentPairSum = INFINITY;
11      
12        // Iterate through the array to calculate required values
13        for (int i = 0; i < arrayLength; ++i) {
14            // Add current element to total sum
15            totalSum += nums[i];
16          
17            // Track the minimum single element in the array
18            minSingleElement = Math.min(minSingleElement, nums[i]);
19          
20            // Track the minimum sum of any two adjacent elements
21            if (i + 1 < arrayLength) {
22                minAdjacentPairSum = Math.min(minAdjacentPairSum, nums[i] + nums[i + 1]);
23            }
24        }
25      
26        // Decision based on array length parity
27        if (arrayLength % 2 == 1) {
28            // For odd-length arrays: remove the minimum single element
29            return totalSum - minSingleElement;
30        }
31      
32        // For even-length arrays: remove the minimum adjacent pair
33        return totalSum - minAdjacentPairSum;
34    }
35}
36
1class Solution {
2public:
3    int maxScore(vector<int>& nums) {
4        const int INF = 1 << 30;  // Large value representing infinity (2^30)
5        int n = nums.size();
6      
7        // Calculate total sum and find minimum single element
8        int totalSum = 0;
9        int minSingleElement = INF;
10      
11        // Find minimum sum of two consecutive elements
12        int minConsecutivePairSum = INF;
13      
14        for (int i = 0; i < n; ++i) {
15            // Add current element to total sum
16            totalSum += nums[i];
17          
18            // Track the minimum single element in the array
19            minSingleElement = min(minSingleElement, nums[i]);
20          
21            // Track the minimum sum of any two consecutive elements
22            if (i + 1 < n) {
23                minConsecutivePairSum = min(minConsecutivePairSum, nums[i] + nums[i + 1]);
24            }
25        }
26      
27        // Decision based on array size parity
28        if (n % 2 == 1) {
29            // For odd-sized arrays: remove the minimum single element
30            return totalSum - minSingleElement;
31        }
32      
33        // For even-sized arrays: remove the minimum consecutive pair
34        return totalSum - minConsecutivePairSum;
35    }
36};
37
1/**
2 * Calculates the maximum score by removing elements from the array
3 * based on specific rules depending on whether the array length is odd or even
4 * @param nums - The input array of numbers
5 * @returns The maximum score after optimal removal
6 */
7function maxScore(nums: number[]): number {
8    const INFINITY: number = Infinity;
9    const arrayLength: number = nums.length;
10  
11    // Initialize variables:
12    // totalSum: sum of all elements in the array
13    // minSingleElement: minimum single element in the array
14    // minPairSum: minimum sum of two consecutive elements
15    let totalSum: number = 0;
16    let minSingleElement: number = INFINITY;
17    let minPairSum: number = INFINITY;
18  
19    // Iterate through the array to calculate required values
20    for (let index: number = 0; index < arrayLength; index++) {
21        // Add current element to total sum
22        totalSum += nums[index];
23      
24        // Track the minimum single element
25        minSingleElement = Math.min(minSingleElement, nums[index]);
26      
27        // Track the minimum sum of two consecutive elements
28        // Only check if there's a next element
29        if (index + 1 < arrayLength) {
30            minPairSum = Math.min(minPairSum, nums[index] + nums[index + 1]);
31        }
32    }
33  
34    // Return the maximum score based on array length parity:
35    // - If odd length: remove the minimum single element
36    // - If even length: remove the minimum pair of consecutive elements
37    return arrayLength % 2 === 1 ? totalSum - minSingleElement : totalSum - minPairSum;
38}
39

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. This is because:

  • Computing the sum of nums takes O(n) time
  • When the length is odd, finding the minimum element takes O(n) time
  • When the length is even, the pairwise(nums) generator creates pairs of consecutive elements, iterating through the array once, and finding the minimum sum of pairs also takes O(n) time overall

The space complexity is O(1). This is because:

  • The sum operation uses constant extra space
  • Finding the minimum value uses constant extra space
  • The pairwise function is a generator that yields pairs on-the-fly without creating a new list, using only constant extra space
  • All other variables (s, intermediate calculations) use constant space

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Misunderstanding the Problem Constraints

A common mistake is assuming that we can keep any arbitrary element or pair of elements at the end, rather than recognizing that the remaining elements must be consecutive in the original array. This leads to incorrect solutions that try to keep the globally smallest elements regardless of their positions.

Incorrect approach:

def maxScore(self, nums: List[int]) -> int:
    total_sum = sum(nums)
    if len(nums) & 1:
        return total_sum - min(nums)
    # WRONG: Finding two smallest elements anywhere in array
    sorted_nums = sorted(nums)
    return total_sum - (sorted_nums[0] + sorted_nums[1])

Correct approach: The remaining elements must be consecutive, so we need to check all consecutive pairs.

2. Off-by-One Error with Pairwise Iteration

When manually implementing the consecutive pair logic without using pairwise, developers often make indexing errors.

Incorrect implementation:

def maxScore(self, nums: List[int]) -> int:
    total_sum = sum(nums)
    if len(nums) & 1:
        return total_sum - min(nums)
  
    # WRONG: This misses the last pair or goes out of bounds
    min_pair = float('inf')
    for i in range(len(nums)):  # Should be len(nums)-1
        min_pair = min(min_pair, nums[i] + nums[i+1])  # IndexError!
    return total_sum - min_pair

Correct manual implementation:

def maxScore(self, nums: List[int]) -> int:
    total_sum = sum(nums)
    if len(nums) & 1:
        return total_sum - min(nums)
  
    min_pair = float('inf')
    for i in range(len(nums) - 1):  # Correct range
        min_pair = min(min_pair, nums[i] + nums[i+1])
    return total_sum - min_pair

3. Import Statement Missing

Forgetting to import pairwise from itertools (available in Python 3.10+) or not handling older Python versions.

Solution for older Python versions:

def maxScore(self, nums: List[int]) -> int:
    total_sum = sum(nums)
    if len(nums) & 1:
        return total_sum - min(nums)
  
    # Manual implementation for Python < 3.10
    min_pair = min(nums[i] + nums[i+1] for i in range(len(nums) - 1))
    return total_sum - min_pair

4. Edge Case Handling

Not considering arrays with very small lengths (1 or 2 elements), though these might be excluded by problem constraints.

Robust solution with edge case handling:

def maxScore(self, nums: List[int]) -> int:
    n = len(nums)
  
    # Handle edge cases
    if n == 1:
        return 0  # No operations possible
    if n == 2:
        return nums[0] + nums[1]  # Only one operation possible
  
    total_sum = sum(nums)
    if n & 1:
        return total_sum - min(nums)
  
    min_pair = min(nums[i] + nums[i+1] for i in range(n - 1))
    return total_sum - min_pair
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which type of traversal does breadth first search do?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More