The challenge

Given a lowercase string of letters (no spaces, no digits), return the length of the longest substring made only of vowels (aeiou).

Examples:

solve("codewarriors");    // → 2  (the "io" in warriors)
solve("suoidea");         // → 3  (the "uoi")
solve("aeioaexaeuoiou");  // → 7  (the "aeuoiou")
solve("bcd");             // → 0
solve("a");               // → 1

The Codewars Kata in the JavaScript track uses aeioaexaeuoiou as a tie-breaker test. The two vowel runs in that string are aeioae (6) and aeuoiou (7) — the answer is 7.

Solution 1: single-pass counter (fastest)

Track the current vowel run length and update the maximum:

function solve(s) {
  const vowels = new Set("aeiou");
  let longest = 0;
  let current = 0;
  for (const ch of s) {
    if (vowels.has(ch)) {
      current++;
      if (current > longest) longest = current;
    } else {
      current = 0;
    }
  }
  return longest;
}

How it works: Walk the string once. If the character is a vowel, extend the current run; otherwise reset to zero. Keep the maximum seen so far. O(n) time, O(1) extra space.

Using new Set("aeiou") makes the membership test O(1). For five characters the difference is negligible, but it scales for larger alphabets.

Solution 2: regex one-liner

function solve(s) {
  const matches = s.match(/[aeiou]+/g);
  return matches ? Math.max(...matches.map(m => m.length)) : 0;
}

How it works: [aeiou]+ matches every run of one or more consecutive vowels. match with the /g flag returns them all as an array (or null if none). Math.max(...arr) picks the longest. The ternary handles the all-consonants case where match returns null.

Solution 3: split on consonants

function solve(s) {
  const parts = s.split(/[^aeiou]+/).filter(Boolean);
  return parts.length ? Math.max(...parts.map(p => p.length)) : 0;
}

How it works: Split on any run of non-vowel characters; the result is an array of vowel-only chunks. .filter(Boolean) drops empty strings (which happen when the input starts or ends with consonants). Math.max picks the largest length.

Walkthrough: aeioaexaeuoiou

Trace the single-pass counter character by character:

Char Vowel? current longest
a yes 1 1
e yes 2 2
i yes 3 3
o yes 4 4
a yes 5 5
e yes 6 6
x no 0 6
a yes 1 6
e yes 2 6
u yes 3 6
o yes 4 6
i yes 5 6
o yes 6 6
u yes 7 7

The first run (aeioae) is length 6. The second run (aeuoiou) is length 7 — that is the winner.

Complexity

Solution Time Space
Single-pass counter O(n) O(1)
Regex [aeiou]+ O(n) O(n)
split on consonants O(n) O(n)

For very long inputs the single-pass loop wins on both speed and memory because it does not allocate any arrays.

Test cases

console.assert(solve("codewarriors") === 2);
console.assert(solve("suoidea") === 3);
console.assert(solve("bcd") === 0);
console.assert(solve("a") === 1);
console.assert(solve("aeiou") === 5);
console.assert(solve("aeioaexaeuoiou") === 7);
console.assert(solve("") === 0);