medium Sort Vowels in a String
Problem Statement
Given a string s, return an updated string t such that all consonants in the string s stay in their original positions while any vowels in the string are reordered according to their ASCII values.
The vowels are 'A', 'E', 'I', 'O', and 'U'. These vowels can appear in lowercase or uppercase. All other letters except vowels are consonants.
Examples
-
Example 1:
- Input: "gamE"
- Expected Output: "gEma"
- Justification: The vowels in "gamE" are 'a' and 'E'. Sorting these by ASCII values, 'E' comes before 'a'. Hence, they are placed in the order 'E', 'a' in the output, while consonants remain unchanged.
-
Example 2:
- Input: "aEiOu"
- Expected Output: "EOaiu"
- Justification: The input consists only of vowels. When we sort them according to their ASCII values, the uppercase vowels come first and then the lowercase vowel comes in 'aiou' order.
-
Example 3:
- Input: "DesIgnGurUs"
- Expected Output: "DIsUgnGerus"
- Justification: The vowels in "DesIgnGurUs" string are 'e', 'I', 'u', and 'U'. Their order according to ASCII value is 'I', 'U', 'e' and 'u'.
Constraints:
- 1 <= s.length <= 105
sconsists only of letters of the English alphabet in uppercase and lowercase.
Try it yourself
Try solving this question here:
✅ Solution Sort Vowels in a String
Problem Statement
Given a string s, return an updated string t such that all consonants in the string s stay in their original positions while any vowels in the string are reordered according to their ASCII values.
The vowels are 'A', 'E', 'I', 'O', and 'U'. These vowels can appear in lowercase or uppercase. All other letters except vowels are consonants.
Examples
-
Example 1:
- Input: "gamE"
- Expected Output: "gEma"
- Justification: The vowels in "gamE" are 'a' and 'E'. Sorting these by ASCII values, 'E' comes before 'a'. Hence, they are placed in the order 'E', 'a' in the output, while consonants remain unchanged.
-
Example 2:
- Input: "aEiOu"
- Expected Output: "EOaiu"
- Justification: The input consists only of vowels. When we sort them according to their ASCII values, the uppercase vowels come first and then the lowercase vowel comes in 'aiou' order.
-
Example 3:
- Input: "DesIgnGurUs"
- Expected Output: "DIsUgnGerus"
- Justification: The vowels in "DesIgnGurUs" string are 'e', 'I', 'u', and 'U'. Their order according to ASCII value is 'I', 'U', 'e' and 'u'.
Constraints:
- 1 <= s.length <= 105
sconsists only of letters of the English alphabet in uppercase and lowercase.
Solution
To solve the problem, we will use the counting sort approach. For that, we'll first identify and count the frequency of each vowel in the input string. This is done using a hash map that maps vowels to their frequencies. After counting, we create a sorted sequence of vowels (both uppercase and lowercase) to act as a guide for reinserting vowels into the string in sorted order. As we reconstruct the string, we replace each vowel with the next vowel in the predefined sorted sequence, ensuring that each vowel is used exactly as many times as it appears in the input string.
This method leverages the fixed number of vowel types (10 in total) to sort and replace vowels efficiently, guaranteeing that the operation stays within a linear time complexity relative to the size of the input string.
Step-by-step Algorithm
-
Initialize Data Structures:
- A
HashMapnamedfrequencyMapto store the count of each vowel. - A
StringBuildernamedresultto construct the final string.
- A
-
Count Vowels:
- Iterate through each character in the input string.
- If the character is a vowel (checked using the
isVowelmethod), increment its count infrequencyMap.
-
Prepare for Reinsertion:
- Define a string
sortedVowelOrdercontaining all possible vowels sorted by ASCII values:"AEIOUaeiou".
- Define a string
-
Reconstruct the String:
- Initialize an index pointer
indexset to 0, to track the current position insortedVowelOrder. - Iterate through each character of the input string again.
- If the character is not a vowel, append it directly to
result. - If it is a vowel, find the next vowel in
sortedVowelOrderwith a remaining count (usingindexto checkfrequencyMap). - Append this vowel to
resultand decrement its count infrequencyMap.
- Initialize an index pointer
Algorithm Walkthrough
Input: "DesIgnGurUs"
Detailed Steps:
-
Counting Vowels:
- D, s, g, n, G, r, s are consonants and are ignored in counting.
- e, I, u, U are vowels.
- After iterating through the string,
frequencyMaplooks like this:- e: 1
- I: 1
- u: 1
- U: 1
-
Sorted Vowel Order:
"AEIOUaeiou" -
Reconstructing the String:
- Start with an empty
result. - Characters: D, s, I, g, n, G, r, U, s are processed directly if consonants.
- For vowels:
- First vowel is 'e', find the smallest unused vowel from
sortedVowelOrder, which is 'I' (since 'A', 'E' are not present, 'I' is the first with a non-zero count). - Replace 'e' with 'I'.
- Next vowel is 'I', proceed in
sortedVowelOrderto 'U' as the next vowel with a non-zero count. - Next, 'u' is replaced by 'e', which is the next in sorted order.
- Lastly, 'U' remains and is replaced by 'u' (the next and only remaining vowel with a non-zero count).
- First vowel is 'e', find the smallest unused vowel from
- The final
resultis constructed: "DIsUgnGerus".
- Start with an empty
Code
import java.util.HashMap;
class Solution {
// Helper method to check if a character is a vowel
private boolean isVowel(char c) {
return "aeiouAEIOU".indexOf(c) != -1;
}
// Sorts the vowels in a string while maintaining the position of consonants
public String countingSortVowels(String s) {
HashMap<Character, Integer> frequencyMap = new HashMap<>();
// Count each vowel's frequency
for (char c : s.toCharArray()) {
if (isVowel(c)) {
frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1);
}
}
// Predefined sorted order of vowels based on ASCII values
String sortedVowelOrder = "AEIOUaeiou";
StringBuilder result = new StringBuilder();
int index = 0; // Pointer for sortedVowelOrder
// Construct the result string with sorted vowels in their positions
for (char c : s.toCharArray()) {
if (!isVowel(c)) {
result.append(c); // Append consonant directly
} else {
// Move to the next vowel with remaining count
while (
index < sortedVowelOrder.length() &&
frequencyMap.getOrDefault(sortedVowelOrder.charAt(index), 0) == 0
) {
index++;
}
// Check if index is within bounds
if (index < sortedVowelOrder.length()) {
result.append(sortedVowelOrder.charAt(index));
frequencyMap.put(
sortedVowelOrder.charAt(index),
frequencyMap.get(sortedVowelOrder.charAt(index)) - 1
);
}
}
}
return result.toString();
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.countingSortVowels("gamE")); // gEma
System.out.println(solution.countingSortVowels("aEiOu")); // Eoaiu
System.out.println(solution.countingSortVowels("DesIgnGurUs")); // DIsUgnGerus
}
}
Complexity Analysis
Time Complexity
- Counting Vowels: Traversing the string to count vowel frequencies requires
, where (n) is the length of the string. - Building the Result: Constructing the final string, including searching for the next vowel in the sorted order with a count greater than zero, theoretically could reach
, where (m) is the maximum length of the sorted vowel string ( sortedVowelOrder). However, since the length ofsortedVowelOrderis constant and small (10), the effective complexity for this part remains. - Overall Time Complexity: Therefore, the total time complexity is
since the operations inside the string traversal are bounded by a constant.
Space Complexity
- Frequency Map: The space complexity for the frequency map is
since the number of distinct vowels (keys) is constant (10). - StringBuilder: The space used by the
StringBuilderisas it stores the rearranged version of the input string. - Overall Space Complexity: Thus, the total space complexity of the algorithm is $O(n)S considering the storage required for the result string.
🤖 Don't fully get this? Learn it with Claude
Stuck on Sort Vowels in a String? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Sort Vowels in a String** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Sort Vowels in a String** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Sort Vowels in a String**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Sort Vowels in a String**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.