Python 100% Solution 37ms!
Heap Sort\n\n|         |Complexity       |Value |\n|---------|-----------------|----------|\n| Runtime | $O(n \log_2(n))$ | 186 ms |\n| Memory  |  O(n)         
# Heap Sort\n\n|         |Complexity       |Value |\n|---------|-----------------|----------|\n| Runtime | $O(n \\log_2(n))$ | 186 ms |\n| Memory  |  O(n)          |19.1 MB |\n\n* Not my best idea.\n* Has additional overhead compared to the built-in sort.\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        vowels = [char for char in s if char in VOWELS]\n        heapify(vowels)\n        return \'\'.join(heappop(vowels) if char in \'aeiouAEIOU\' else char for char in s)\n```\n\n# Built-In Comparison Sort\n\n|         |Complexity     |Value |\n|---------|-----------------|----------|\n| Runtime | $O(n \\log_2(n))$ | 123 ms |\n| Memory  |  O(n)          |19.4 MB |\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        vowels = iter(sorted(char for char in s if char in VOWELS))\n        return \'\'.join(next(vowels) if char in VOWELS else char for char in s)\n```\n\n# Counting Sort\n\n|         |Complexity |Value    |\n|---------|-----------|---------|\n| Runtime | $O(n)$    | 131 ms  |\n| Memory  |  O(10)    | 18.3 MB |\n\n* The extra counts in the last bucket get discarded.\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        counts = [0] * 10\n        for c in s:\n            i = VOWELS.find(c)\n            counts[i] += 1\n        vowels = chain.from_iterable(map(repeat, VOWELS, counts))\n        return \'\'.join(next(vowels) if char in VOWELS else char for char in s)\n```\n\n# Counting Sort with Counter\n\n|         |Complexity |Value    |\n|---------|-----------|---------|\n| Runtime | $O(n)$    | 97 ms  |\n| Memory  |  O(52)    | 18.4 MB |\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        counts = Counter(s)\n        vowels = chain.from_iterable(repeat(vowel, counts[vowel]) for vowel in VOWELS)\n        return \'\'.join(next(vowels) if char in VOWELS else char for char in s)\n```\n\n# Counting Sort with Chain Flattening\n\n|         |Complexity |Value    |\n|---------|-----------|---------|\n| Runtime | $O(n)$    | 71 ms   |\n| Memory  |  O(1)     | 18.3 MB |\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        vowels = chain.from_iterable(repeat(vowel, s.count(vowel)) for vowel in VOWELS)\n        return \'\'.join(next(vowels) if char in VOWELS else char for char in s)\n```\n\n# Counting Sort Rev 2\n\n|         |Complexity |Value    |\n|---------|-----------|---------|\n| Runtime | $O(10n)$  | 42 ms   |\n| Memory  |  O(10)    | 17.6 MB |\n\n* Sometimes more operations with less overhead gives a faster solution.\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nTRANS = str.maketrans(VOWELS, \'_\' * 10)\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        counts = tuple(map(s.count, VOWELS))\n        s = s.translate(TRANS)\n        for vowel, count in zip(VOWELS, counts):\n            s = s.replace(\'_\', vowel, count)\n        return s\n```\n\n## With Less State\n\n\n|         |Complexity |Value    |\n|---------|-----------|---------|\n| Runtime | $O(10n)$  | 37 ms   |\n| Memory  |  O(1)     | 17.8 MB |\n\n```python\nVOWELS = \'AEIOUaeiou\'\n\nTRANS = str.maketrans(VOWELS, \'_\' * 10)\n\nclass Solution:\n    def sortVowels(self, s: str) -> str:\n        s2 = s.translate(TRANS)\n        for vowel in VOWELS:\n            s2 = s2.replace(\'_\', vowel, s.count(vowel))\n        return s2\n```
['Python3']