Skip to main content
Back to problems
#3913
Medium Algorithms

Sort vowels by frequency

62.8% acceptance
May 13, 2026
49
4
You are given a string s consisting of lowercase English characters. Rearrange only the vowels in the string so that they appear in non-increasing order of their frequency. If multiple vowels have the same frequency, order them by the position of their first occurrence in s. Return the modified string. Vowels are 'a', 'e', 'i', 'o', and 'u'. The frequency of a letter is the number of times it occurs in the string.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn sort_vowels(s: String) -> String {
    let bytes: Vec<u8> = s.into_bytes();
    let is_vowel = |b: u8| matches!(b, b'a' | b'e' | b'i' | b'o' | b'u');
    let mut count = [0i32; 5];
    let mut first = [usize::MAX; 5];
    let vowel_idx = |b: u8| -> usize {
      match b {
        b'a' => 0,
        b'e' => 1,
        b'i' => 2,
        b'o' => 3,
        b'u' => 4,
        _ => unreachable!(),
      }
    };
    let vowel_byte = |i: usize| -> u8 {
      [b'a', b'e', b'i', b'o', b'u'][i]
    };
    for (i, &b) in bytes.iter().enumerate() {
      if is_vowel(b) {
        let vi = vowel_idx(b);
        count[vi] += 1;
        if first[vi] == usize::MAX {
          first[vi] = i;
        }
      }
    }
    let mut order: Vec<usize> = (0..5).filter(|&i| count[i] > 0).collect();
    order.sort_by(|&a, &b| {
      count[b].cmp(&count[a]).then(first[a].cmp(&first[b]))
    });
    let mut sorted_vowels: Vec<u8> = Vec::new();
    for vi in order {
      for _ in 0..count[vi] {
        sorted_vowels.push(vowel_byte(vi));
      }
    }
    let mut result = bytes.clone();
    let mut idx = 0;
    for i in 0..result.len() {
      if is_vowel(result[i]) {
        result[i] = sorted_vowels[idx];
        idx += 1;
      }
    }
    String::from_utf8(result).unwrap()
  }
}