3085. Minimum Deletions to Make String K-Special
Problem Description
You are given a string word
and an integer k
.
We consider word
to be k-special if |freq(word[i]) - freq(word[j])| <= k
for all indices i
and j
in the string.
Here, freq(x)
denotes the frequency of the character x
in word
, and |y|
denotes the absolute value of y
.
Return the minimum number of characters you need to delete to make word
k-special.
Intuition
The problem boils down to adjusting the frequency of characters such that the difference between the maximum and minimum frequencies does not exceed k
. Our task is to minimize deletions to achieve this.
-
Counting Frequencies: First, count the frequency of each character. We represent these frequencies in an array
nums
. -
Enumeration Strategy: We attempt to find the "ideal" minimum frequency
v
within the range[0, n]
, wheren
is the length ofword
. This minimum frequencyv
helps us determine how much we need to delete to make the frequencies of characters differ by at mostk
. -
Function Calculation: For any chosen
v
, calculate the deletion count:- If a character occurs less than
v
, we delete all of its occurrences. - If a character's frequency exceeds
v + k
, we reduce it tov + k
.
- If a character occurs less than
The overall approach is to explore all possible values of v
and compute the number of deletions needed for each. The smallest number of deletions among these gives the desired result. This technique ensures that we find the minimal deletions necessary to satisfy the k-special conditions.
Solution Approach
The primary goal of the solution is to efficiently determine the minimum number of deletions required to make the string k-special
. Here's how it is achieved:
-
Character Frequency Count: Use Python's
Counter
from thecollections
module to count the occurrences of each character inword
. The frequencies are then extracted into a listnums
. -
Enumeration of Minimum Frequency: Iterate over potential minimum frequencies,
v
, from0
ton
(the length of the word), to determine the minimal deletion strategy for each candidatev
. -
Function
f(v)
Calculation:- The function
f(v)
is crafted to compute the number of deletions required for a givenv
. - For each frequency
x
innums
:- If
x
is less thanv
, all occurrences of the character contributing to this frequency are deleted. - If
x
exceedsv + k
, reduce the frequency tov + k
, resulting in deletions ofx - v - k
occurrences.
- If
- The function accumulates the total deletions needed based on these rules.
- The function
-
Result Extraction: The answer is the minimum value obtained from evaluating
f(v)
over all possiblev
. This represents the fewest deletions needed to satisfy thek-special
condition forword
.
By evaluating every viable v
, the algorithm swiftly identifies the optimal frequency range adjustments required to achieve balance among character frequencies within the constraints of k
.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider the string word = "aabbcc"
and k = 1
.
Step 1: Character Frequency Count
Using Python's collections.Counter
, we count the frequency of each character in word
. This results in:
a
appears 2 timesb
appears 2 timesc
appears 2 times
Thus, the frequency list nums
becomes [2, 2, 2]
.
Step 2: Enumeration of Minimum Frequency
We evaluate potential minimum frequencies v
from 0
to 6
(the length of the word word
).
Step 3: Function f(v)
Calculation
For each v
, calculate the necessary deletions:
-
If
v = 0
:- All characters already have frequency greater than
0
. - No deletions are needed because the condition
|freq(word[i]) - freq(word[j])| <= 1
is already satisfied.
- All characters already have frequency greater than
-
If
v = 1
:- No deletion for any character as all frequencies are either
1
or1 + k = 2
. - Total deletions: 0
- No deletion for any character as all frequencies are either
-
If
v = 2
:- Again, no deletions are needed because all frequencies match
v
exactly. - Total deletions: 0
- Again, no deletions are needed because all frequencies match
All frequencies from v = 0
to v = 2
already satisfy the k-special
condition with zero deletions.
Step 4: Result Extraction
The minimum deletions required across all v
is 0
. Thus, 0
deletions are needed to make word
k-special with k = 1
.
By considering how frequencies align with possible v
values, this method effectively determines minimal adjustments necessary to satisfy the problem constraints.
Solution Implementation
1from collections import Counter
2
3class Solution:
4 def minimumDeletions(self, word: str, k: int) -> int:
5 # Inner function to calculate the minimum deletions required for a given threshold
6 def f(threshold: int) -> int:
7 deletions = 0
8 for frequency in frequencies:
9 # If frequency is less than the threshold, we need to delete all occurrences
10 if frequency < threshold:
11 deletions += frequency
12 # If frequency is greater than the threshold plus k, delete the excess
13 elif frequency > threshold + k:
14 deletions += frequency - threshold - k
15 return deletions
16
17 # Get a list of the frequencies of each character in the word
18 frequencies = Counter(word).values()
19 # Calculate and return the minimum deletions for all possible threshold values
20 return min(f(threshold) for threshold in range(len(word) + 1))
21
1import java.util.ArrayList;
2import java.util.List;
3
4class Solution {
5 // List to store the frequencies of characters in the input word
6 private List<Integer> characterFrequencies = new ArrayList<>();
7
8 // Method to calculate the minimum number of deletions required
9 public int minimumDeletions(String word, int k) {
10 // Array to store frequency of each character in the English alphabet
11 int[] frequencyArray = new int[26];
12 int wordLength = word.length();
13
14 // Calculate frequency of each character in the input word
15 for (int i = 0; i < wordLength; ++i) {
16 ++frequencyArray[word.charAt(i) - 'a'];
17 }
18
19 // Add non-zero frequencies to the characterFrequencies list
20 for (int frequency : frequencyArray) {
21 if (frequency > 0) {
22 characterFrequencies.add(frequency);
23 }
24 }
25
26 // Initialize the answer with the length of the word
27 int minimumDeletions = wordLength;
28
29 // Find the minimum deletions possible by checking for every potential value `v` from 0 to word length
30 for (int i = 0; i <= wordLength; ++i) {
31 // Update minimumDeletions with the smaller value between the current and the new calculation from helper function `f`
32 minimumDeletions = Math.min(minimumDeletions, calculateDeletions(i, k));
33 }
34 return minimumDeletions;
35 }
36
37 // Helper method to calculate deletions given a threshold `v` and limit `k`
38 private int calculateDeletions(int v, int k) {
39 int deletions = 0;
40
41 // Iterate over each frequency in the list
42 for (int frequency : characterFrequencies) {
43 // If the frequency is less than `v`, add the full frequency to deletions
44 if (frequency < v) {
45 deletions += frequency;
46 }
47 // If the frequency exceeds `v + k`, calculate the deletions needed to reduce it
48 else if (frequency > v + k) {
49 deletions += frequency - v - k;
50 }
51 }
52 return deletions;
53 }
54}
55
1#include <vector>
2#include <string>
3#include <algorithm> // For std::min
4using namespace std;
5
6class Solution {
7public:
8 int minimumDeletions(string word, int k) {
9 // Array to store the frequency of each character in the word.
10 int frequency[26] = {};
11
12 // Increment the appropriate frequency count for each character in 'word'.
13 for (char& c : word) {
14 ++frequency[c - 'a'];
15 }
16
17 // Vector to store the frequencies of all the characters that appear in the word.
18 vector<int> characterFrequencies;
19 for (int freq : frequency) {
20 if (freq > 0) {
21 characterFrequencies.push_back(freq);
22 }
23 }
24
25 int wordSize = word.size();
26 int minimumDeletionsResult = wordSize;
27
28 // Lambda function to calculate deletions needed to balance frequencies.
29 auto calculateDeletions = [&](int targetFrequency) {
30 int deletions = 0;
31 for (int freq : characterFrequencies) {
32 if (freq < targetFrequency) { // Frequency is too low
33 deletions += freq;
34 } else if (freq > targetFrequency + k) { // Frequency too high to be adjusted by 'k'
35 deletions += (freq - targetFrequency - k);
36 }
37 }
38 return deletions;
39 };
40
41 // Try all target frequencies from 0 to the size of the word to determine minimum deletions.
42 for (int target = 0; target <= wordSize; ++target) {
43 minimumDeletionsResult = min(minimumDeletionsResult, calculateDeletions(target));
44 }
45
46 return minimumDeletionsResult;
47 }
48};
49
1// Function to calculate the minimum number of deletions required from the word
2// such that for any character frequency `x`, either `x < v` or `x > v + k`
3function minimumDeletions(word: string, k: number): number {
4 // Create an array to store the frequency of each letter in the word
5 const frequency: number[] = Array(26).fill(0);
6
7 // Populate the frequency array
8 for (const ch of word) {
9 frequency[ch.charCodeAt(0) - 97]++;
10 }
11
12 // Filter out zero frequencies, only keep those greater than zero
13 const nums = frequency.filter(count => count > 0);
14
15 // Helper function to calculate deletions needed for a given target value v
16 const f = (v: number): number => {
17 let deletions = 0;
18 for (const x of nums) {
19 if (x < v) {
20 deletions += x;
21 } else if (x > v + k) {
22 deletions += x - v - k;
23 }
24 }
25 return deletions;
26 };
27
28 // Calculate the minimum deletions required by considering all possible target frequencies
29 return Math.min(...Array.from({ length: word.length + 1 }, (_, i) => f(i)));
30}
31
Time and Space Complexity
The time complexity of the code is O(n ร |\Sigma|)
because for each unique character frequency in the word
, which can be at most n
, we are iterating over a range of size n + 1
and calculating the function f(v)
, which is O(|\Sigma|)
. Since |\Sigma|
is limited to 26 in this particular problem, this results in a linear time complexity relative to the length of the word.
The space complexity of the code is O(|\Sigma|)
because we use a Counter to store the frequency of each character in the word
, which uses space proportional to the size of the character set, |\Sigma|
, which is at most 26.
Learn more about how to find time and space complexity quickly.
How many times is a tree node visited in a depth first search?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
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
Want a Structured Path to Master System Design Too? Donโt Miss This!