Facebook Pixel

3223. Minimum Length of String After Operations

MediumHash TableStringCounting
Leetcode Link

Problem Description

You are given a string s and can repeatedly perform a specific deletion operation on it.

The deletion operation works as follows:

  • Pick any index i in the string where the character s[i] appears at least once to its left AND at least once to its right
  • When you pick such an index i, you must delete exactly two characters:
    • The closest occurrence of s[i] to the left of position i
    • The closest occurrence of s[i] to the right of position i

You can perform this operation as many times as you want (including zero times). Your goal is to find the minimum possible length of the string after performing these operations optimally.

For example, if you have the string "aabcbaa" and choose index 3 (where s[3] = 'c' is not valid since 'c' doesn't appear on both sides), but if you choose index 2 (where s[2] = 'b'), you would delete the 'b' at index 1 (closest to the left) and the 'b' at index 4 (closest to the right), resulting in "aacaa".

The key insight is that for each unique character in the string:

  • If it appears an odd number of times, you can reduce it down to exactly 1 occurrence
  • If it appears an even number of times, you can reduce it down to exactly 2 occurrences

This is because each operation removes 2 occurrences of the same character, so you keep removing pairs until you can't form a valid triplet anymore (one in the middle with at least one on each side).

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

Intuition

Let's think about what happens when we perform the deletion operation. Each time we delete, we remove exactly 2 occurrences of the same character - one from the left and one from the right of our chosen position.

Consider a character that appears n times in the string. To perform a valid deletion, we need at least 3 occurrences of that character (one in the middle to choose as index i, one on the left, and one on the right). After the deletion, we have n - 2 occurrences left.

If we keep applying this operation:

  • Starting with n occurrences, we get n - 2, then n - 4, then n - 6, and so on
  • We can continue until we have fewer than 3 occurrences remaining

This means:

  • If n is odd (like 5, 7, 9...), we can reduce it to: 5→3→1, or 7→5→3→1, etc. We always end up with exactly 1 occurrence
  • If n is even (like 4, 6, 8...), we can reduce it to: 4→2, or 6→4→2, etc. We always end up with exactly 2 occurrences

The crucial observation is that each character's final count is independent of other characters. We can process each unique character separately and determine its minimum possible count based on whether its initial count is odd or even.

Therefore, the minimum length of the final string is simply the sum of the minimum counts for each unique character:

  • For characters appearing an odd number of times: contribute 1 to the final length
  • For characters appearing an even number of times: contribute 2 to the final length

This leads us to count the frequency of each character and apply the odd/even rule to determine the minimum achievable length.

Solution Approach

The implementation uses a counting approach with Python's Counter to efficiently solve this problem.

Step 1: Count Character Frequencies

We use Counter(s) from Python's collections module to count the occurrences of each character in the string. This gives us a dictionary where keys are characters and values are their frequencies.

cnt = Counter(s)

For example, if s = "aabcbaa", then cnt = {'a': 4, 'b': 2, 'c': 1}.

Step 2: Calculate Minimum Length

We iterate through all the frequency values and apply our rule:

  • If a character appears an odd number of times (x & 1 is true), it contributes 1 to the final length
  • If a character appears an even number of times (x & 1 is false), it contributes 2 to the final length
return sum(1 if x & 1 else 2 for x in cnt.values())

The expression x & 1 is a bitwise operation that checks if x is odd (returns 1 if odd, 0 if even). This is equivalent to x % 2 but slightly more efficient.

Complete Solution:

class Solution:
    def minimumLength(self, s: str) -> int:
        cnt = Counter(s)
        return sum(1 if x & 1 else 2 for x in cnt.values())

Time Complexity: O(n) where n is the length of the string, as we need to count all characters once.

Space Complexity: O(k) where k is the number of unique characters in the string (at most 26 for lowercase English letters).

This elegant solution avoids simulating the actual deletion process and directly computes the final result based on the mathematical pattern we discovered.

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Let's walk through the solution with the string s = "aabbccc".

Step 1: Count character frequencies

  • 'a' appears 2 times
  • 'b' appears 2 times
  • 'c' appears 3 times

Step 2: Apply the odd/even rule for each character

For 'a' (appears 2 times - even):

  • We can perform deletion operations: Start with "aa" in context of the full string
  • Since we need at least 3 occurrences to perform a deletion and we only have 2, we cannot reduce further
  • Minimum occurrences: 2

For 'b' (appears 2 times - even):

  • Similar to 'a', we have only 2 occurrences
  • Cannot perform any deletion (need at least 3)
  • Minimum occurrences: 2

For 'c' (appears 3 times - odd):

  • We have exactly 3 occurrences: "ccc"
  • We can perform one deletion: choose the middle 'c', delete the left and right 'c'
  • After deletion: 3 - 2 = 1 occurrence remains
  • Minimum occurrences: 1

Step 3: Calculate the final minimum length

  • Total minimum length = 2 (from 'a') + 2 (from 'b') + 1 (from 'c') = 5

Let's verify with another example: s = "aaaa"

  • 'a' appears 4 times (even)
  • We can perform deletions: 4 → 2 (choose any middle 'a', delete one from left and right)
  • Minimum occurrences: 2
  • Final minimum length = 2

The algorithm correctly identifies that characters with odd counts reduce to 1, and characters with even counts reduce to 2, giving us the minimum possible string length.

Solution Implementation

1from collections import Counter
2
3class Solution:
4    def minimumLength(self, s: str) -> int:
5        # Count the frequency of each character in the string
6        char_count = Counter(s)
7      
8        # Calculate the minimum length after operations
9        # For each character:
10        # - If frequency is odd: keep 1 character (palindrome center)
11        # - If frequency is even: keep 2 characters (one for each side)
12        total_length = 0
13        for frequency in char_count.values():
14            if frequency % 2 == 1:  # Odd frequency
15                total_length += 1
16            else:  # Even frequency
17                total_length += 2
18      
19        return total_length
20
1class Solution {
2    public int minimumLength(String s) {
3        // Array to store frequency count of each character (a-z)
4        int[] charFrequency = new int[26];
5      
6        // Count frequency of each character in the string
7        for (int i = 0; i < s.length(); i++) {
8            charFrequency[s.charAt(i) - 'a']++;
9        }
10      
11        // Calculate minimum length after operations
12        int minimumLength = 0;
13      
14        // For each character that appears in the string
15        for (int frequency : charFrequency) {
16            if (frequency > 0) {
17                // If frequency is odd, keep 1 character
18                // If frequency is even, keep 2 characters
19                minimumLength += (frequency % 2 == 1) ? 1 : 2;
20            }
21        }
22      
23        return minimumLength;
24    }
25}
26
1class Solution {
2public:
3    int minimumLength(string s) {
4        // Array to store frequency count of each character ('a' to 'z')
5        int charFrequency[26]{};
6      
7        // Count the frequency of each character in the string
8        for (char& ch : s) {
9            ++charFrequency[ch - 'a'];
10        }
11      
12        // Calculate the minimum length after operations
13        int minLength = 0;
14      
15        // For each character, determine how many should remain
16        for (int frequency : charFrequency) {
17            if (frequency > 0) {
18                // If frequency is odd, keep 1 character
19                // If frequency is even, keep 2 characters
20                minLength += (frequency % 2 == 1) ? 1 : 2;
21            }
22        }
23      
24        return minLength;
25    }
26};
27
1/**
2 * Calculates the minimum length of string after removing palindromic subsequences
3 * @param s - Input string to process
4 * @returns The minimum possible length after removals
5 */
6function minimumLength(s: string): number {
7    // Map to store the frequency count of each character
8    const characterCount = new Map<string, number>();
9  
10    // Count the frequency of each character in the string
11    for (const character of s) {
12        characterCount.set(character, (characterCount.get(character) || 0) + 1);
13    }
14  
15    // Calculate the minimum length based on character frequencies
16    let minimumResultLength = 0;
17  
18    // For each character frequency:
19    // - If frequency is odd, we can reduce it to 1 (keep 1 character)
20    // - If frequency is even, we can reduce it to 2 (keep 2 characters)
21    for (const frequency of characterCount.values()) {
22        minimumResultLength += (frequency & 1) ? 1 : 2;
23    }
24  
25    return minimumResultLength;
26}
27

Time and Space Complexity

The time complexity is O(n), where n is the length of the string s. This is because the Counter(s) operation needs to iterate through each character in the string exactly once to count the frequency of each character.

The space complexity is O(|Σ|), where |Σ| is the size of the character set. In this problem, assuming we're dealing with lowercase English letters, |Σ| = 26. The Counter object stores at most one entry for each unique character in the string, which is bounded by the size of the alphabet. The subsequent sum operation with the generator expression uses O(1) additional space.

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

Common Pitfalls

Pitfall 1: Misunderstanding the Deletion Operation

The Mistake: Many people initially think they need to simulate the actual deletion process by finding valid indices and removing characters step by step. This leads to complex implementations with nested loops trying to track positions and update the string after each deletion.

# INCORRECT approach - trying to simulate deletions
def minimumLength(self, s: str) -> int:
    s_list = list(s)
    changed = True
    while changed:
        changed = False
        for i in range(len(s_list)):
            # Try to find left and right occurrences
            left_idx = -1
            right_idx = -1
            # Complex logic to find and delete...
            # This becomes very messy and inefficient

The Solution: Recognize that you don't need to simulate the process. The key insight is mathematical: each operation removes exactly 2 occurrences of the same character. Therefore, you can directly calculate the final state based on character frequencies.

Pitfall 2: Incorrect Final Count Logic

The Mistake: Assuming that characters with even frequencies can be reduced to 0, or that all characters can be reduced to at most 1.

# INCORRECT - assuming even frequencies go to 0
def minimumLength(self, s: str) -> int:
    cnt = Counter(s)
    return sum(1 for x in cnt.values() if x % 2 == 1)

Why it's wrong: For a character to be deletable, you need at least 3 occurrences (one in the middle, one on each side). With only 2 occurrences, you cannot form a valid triplet for deletion. Therefore:

  • Even frequencies (2, 4, 6, ...) reduce to 2
  • Odd frequencies (1, 3, 5, ...) reduce to 1

Pitfall 3: Over-complicating the Modulo Check

The Mistake: Using complex conditional logic when a simple modulo or bitwise operation suffices.

# Overly complex
def minimumLength(self, s: str) -> int:
    cnt = Counter(s)
    result = 0
    for freq in cnt.values():
        if freq == 1:
            result += 1
        elif freq == 2:
            result += 2
        elif freq % 2 == 0:
            result += 2
        else:
            result += 1
    return result

The Solution: Simplify to a single conditional: odd frequencies contribute 1, even frequencies contribute 2.

return sum(1 if freq % 2 == 1 else 2 for freq in cnt.values())
Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

Which of the following array represent a max heap?


Recommended Readings

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

Load More