Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reverse Vowels of a String.

Given a string s, reverse only the vowels in the string and return it. Vowels are a, e, i, o, u in both lower and upper case.

Algorithm — O(n) time, O(n) space:

Use two pointers (left, right) starting at both ends of the codepoint list. Advance each pointer inward until it lands on a vowel, then swap the two vowels and continue. When the pointers cross, all vowels have been reversed while consonants stay in place.

Example:

s = "IceCreAm"   →   "AceCreIm"
s = "leetcode"   →   "leotcede"
from std.collections import Set
from std.collections.string import Codepoint
from std.testing import assert_equal, TestSuite


# ═══════════════════════════════════════════════════════════════
#  Implementation
# ═══════════════════════════════════════════════════════════════

def reverse_vowels(s: String) -> String:
    """Reverse only the vowels in `s`, leaving consonants in place."""
    var codepoints = [code for code in s.codepoints()]
    var n = len(codepoints)
    if n == 0 or n == 1:
        return s

    var vowels = Set([Int(code) for code in "aeiouAEIOU".codepoints()])

    var left = 0
    var right = n - 1

    while left < right:
        # Advance left until it lands on a vowel.
        while left < right and Int(codepoints[left]) not in vowels:
            left += 1

        # Advance right until it lands on a vowel.
        while left < right and Int(codepoints[right]) not in vowels:
            right -= 1

        if left < right:
            codepoints.swap_elements(left, right)
            left += 1
            right -= 1

    var result = String()
    for code in codepoints:
        result.append(code)

    return result


# ═══════════════════════════════════════════════════════════════
#  Tests
# ═══════════════════════════════════════════════════════════════

def test_example_1() raises:
    assert_equal(reverse_vowels("IceCreAm"), "AceCreIm")


def test_example_2() raises:
    assert_equal(reverse_vowels("leetcode"), "leotcede")


def test_empty_string() raises:
    assert_equal(reverse_vowels(""), "")


def test_single_char_consonant() raises:
    assert_equal(reverse_vowels("b"), "b")


def test_single_char_vowel() raises:
    assert_equal(reverse_vowels("a"), "a")


def test_no_vowels() raises:
    assert_equal(reverse_vowels("bcdfg"), "bcdfg")


def test_all_vowels() raises:
    assert_equal(reverse_vowels("aeiou"), "uoiea")


def test_vowels_in_mixed_case() raises:
    assert_equal(reverse_vowels("AEIOU"), "UOIEA")


def test_only_middle_vowel() raises:
    assert_equal(reverse_vowels("abcd"), "abcd")


def test_multiple_vowels_odd_length() raises:
    assert_equal(reverse_vowels("hello"), "holle")


def test_vowels_at_ends() raises:
    assert_equal(reverse_vowels("amazing"), "imazang")


def test_palindrome_with_vowels() raises:
    assert_equal(reverse_vowels("racecar"), "racecar")


def test_spaces_and_punctuation() raises:
    assert_equal(reverse_vowels("a!e@i#o$u%"), "u!o@i#e$a%")


def test_uppercase_and_lowercase() raises:
    # Vowels are reversed as-is; case stays with each character.
    assert_equal(reverse_vowels("AaEeIiOoUu"), "uUoOiIeEaA")


def main() raises:
    TestSuite.discover_tests[__functions_in_module()]().run()

View source on GitHub