3223. Minimum Length of String After Operations
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 characters[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 positioni
- The closest occurrence of
s[i]
to the right of positioni
- The closest occurrence of
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).
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 getn - 2
, thenn - 4
, thenn - 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 EvaluatorExample 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())
Which of the following array represent a max heap?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!