3136. Valid Word
Problem Description
You need to determine if a given word is valid based on specific criteria.
A word is considered valid if it meets ALL of the following conditions:
- Length requirement: The word must contain at least 3 characters
- Character composition: The word can only contain:
- Digits (0-9)
- English letters (both uppercase and lowercase)
- No special characters or symbols are allowed
- Vowel requirement: The word must contain at least one vowel
- Vowels are:
'a'
,'e'
,'i'
,'o'
,'u'
and their uppercase versions'A'
,'E'
,'I'
,'O'
,'U'
- Vowels are:
- Consonant requirement: The word must contain at least one consonant
- A consonant is any English letter that is not a vowel
Given a string word
, you need to return true
if the word satisfies all four conditions above, otherwise return false
.
Example scenarios:
- A word like
"a1b"
would be valid (length ≥ 3, contains only valid characters, has vowel 'a', has consonant 'b') - A word like
"123"
would be invalid (no vowels or consonants, only digits) - A word like
"ab"
would be invalid (length < 3) - A word like
"a@b"
would be invalid (contains special character '@') - A word like
"aaa"
would be invalid (no consonants)
Intuition
The problem asks us to validate a word based on four distinct criteria. The key insight is that we need to check each condition systematically, and if any condition fails, we can immediately return false
.
Let's think about how to approach each requirement:
-
Length check: This is straightforward - we can check
len(word) < 3
at the very beginning. If the word is too short, there's no need to check anything else. -
Character validation: As we traverse through each character in the word, we need to ensure it's either a digit or a letter. The built-in method
isalnum()
perfectly handles this - it returnstrue
only for alphanumeric characters. -
Vowel and Consonant tracking: Here's where we need to be clever. Instead of making two separate passes through the string, we can track both requirements in a single pass. We'll use two boolean flags:
has_vowel
: Initiallyfalse
, set totrue
when we encounter any vowelhas_consonant
: Initiallyfalse
, set totrue
when we encounter any consonant
The trick is to pre-define a set of vowels "aeiouAEIOU"
. When we encounter a letter (checked using isalpha()
), we can quickly determine if it's a vowel by checking membership in this set. If it's a letter but not in the vowel set, it must be a consonant.
By the end of our traversal, both flags must be true
for the word to be valid. This approach is efficient because:
- We only make one pass through the string
- We exit early if we find an invalid character
- Set membership checking is O(1) on average
- We don't need to store or count individual vowels/consonants, just track their presence
Solution Approach
Let's implement the solution step by step based on our validation criteria:
Step 1: Check minimum length
if len(word) < 3:
return False
If the word has fewer than 3 characters, we immediately return false
since it fails the first requirement.
Step 2: Initialize tracking variables
has_vowel = has_consonant = False
vs = set("aeiouAEIOU")
- We create two boolean flags to track whether we've found at least one vowel and one consonant
- We define a set
vs
containing all vowels (both lowercase and uppercase) for O(1) lookup time
Step 3: Iterate through each character
for c in word:
We examine each character in the word one by one.
Step 4: Validate character type
if not c.isalnum(): return False
For each character, we first check if it's alphanumeric (either a letter or digit). If we encounter any special character or symbol, the word is invalid, so we return false
immediately.
Step 5: Check for vowels and consonants
if c.isalpha(): if c in vs: has_vowel = True else: has_consonant = True
If the character is a letter (not a digit):
- We check if it's in our vowel set
vs
- If yes, we set
has_vowel = True
- If no, it must be a consonant, so we set
has_consonant = True
Note that digits don't affect our vowel/consonant requirements - they're valid characters but neither vowels nor consonants.
Step 6: Final validation
return has_vowel and has_consonant
After processing all characters, we return true
only if we've found both at least one vowel AND at least one consonant. If either flag remains false
, the word is invalid.
This approach efficiently validates the word in a single pass with O(n) time complexity, where n is the length of the word.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with the word "Ex4mple"
:
Step 1: Check minimum length
len("Ex4mple") = 7
, which is ≥ 3 ✓- Continue to next step
Step 2: Initialize tracking variables
has_vowel = False
has_consonant = False
vs = {"a", "e", "i", "o", "u", "A", "E", "I", "O", "U"}
Step 3-5: Process each character
Character | isalnum() ? | isalpha() ? | In vowel set? | Action | has_vowel | has_consonant |
---|---|---|---|---|---|---|
'E' | Yes ✓ | Yes | Yes ('E' in vs) | Set has_vowel = True | True | False |
'x' | Yes ✓ | Yes | No ('x' not in vs) | Set has_consonant = True | True | True |
'4' | Yes ✓ | No | N/A | Skip (digit) | True | True |
'm' | Yes ✓ | Yes | No ('m' not in vs) | Already have consonant | True | True |
'p' | Yes ✓ | Yes | No ('p' not in vs) | Already have consonant | True | True |
'l' | Yes ✓ | Yes | No ('l' not in vs) | Already have consonant | True | True |
'e' | Yes ✓ | Yes | Yes ('e' in vs) | Already have vowel | True | True |
Step 6: Final validation
has_vowel = True
(found 'E' and 'e')has_consonant = True
(found 'x', 'm', 'p', 'l')- Return
has_vowel AND has_consonant = True AND True = True
The word "Ex4mple"
is valid ✓
Counter-example with "123"
(invalid - no vowels or consonants):
Step 1: len("123") = 3
✓
Step 2: Initialize has_vowel = False
, has_consonant = False
Step 3-5: Process characters:
- '1':
isalnum()
✓, butisalpha()
✗ → skip (digit) - '2':
isalnum()
✓, butisalpha()
✗ → skip (digit) - '3':
isalnum()
✓, butisalpha()
✗ → skip (digit)
Step 6: Return False AND False = False
The word "123"
is invalid because it contains no vowels or consonants.
Solution Implementation
1class Solution:
2 def isValid(self, word: str) -> bool:
3 """
4 Validates if a word meets specific criteria:
5 - Minimum length of 3 characters
6 - Contains only alphanumeric characters
7 - Has at least one vowel
8 - Has at least one consonant
9
10 Args:
11 word: Input string to validate
12
13 Returns:
14 bool: True if word is valid, False otherwise
15 """
16 # Check minimum length requirement
17 if len(word) < 3:
18 return False
19
20 # Initialize flags to track presence of vowels and consonants
21 has_vowel = False
22 has_consonant = False
23
24 # Define set of vowels (both lowercase and uppercase)
25 vowels = set("aeiouAEIOU")
26
27 # Iterate through each character in the word
28 for char in word:
29 # Check if character is alphanumeric (letter or digit)
30 if not char.isalnum():
31 return False
32
33 # If character is a letter, determine if it's a vowel or consonant
34 if char.isalpha():
35 if char in vowels:
36 has_vowel = True
37 else:
38 has_consonant = True
39
40 # Word is valid only if it contains both vowel(s) and consonant(s)
41 return has_vowel and has_consonant
42
1class Solution {
2 public boolean isValid(String word) {
3 // Check if word has minimum length of 3
4 if (word.length() < 3) {
5 return false;
6 }
7
8 // Track whether word contains required characters
9 boolean hasVowel = false;
10 boolean hasConsonant = false;
11
12 // Create a lookup table for vowels (a, e, i, o, u)
13 boolean[] isVowelLookup = new boolean[26];
14 for (char vowel : "aeiou".toCharArray()) {
15 isVowelLookup[vowel - 'a'] = true;
16 }
17
18 // Iterate through each character in the word
19 for (char currentChar : word.toCharArray()) {
20 if (Character.isAlphabetic(currentChar)) {
21 // For alphabetic characters, check if vowel or consonant
22 char lowercaseChar = Character.toLowerCase(currentChar);
23 int alphabetIndex = lowercaseChar - 'a';
24
25 if (isVowelLookup[alphabetIndex]) {
26 hasVowel = true;
27 } else {
28 hasConsonant = true;
29 }
30 } else if (!Character.isDigit(currentChar)) {
31 // If character is neither alphabetic nor digit, word is invalid
32 return false;
33 }
34 // Digits are allowed but don't affect vowel/consonant requirements
35 }
36
37 // Word is valid only if it contains at least one vowel AND one consonant
38 return hasVowel && hasConsonant;
39 }
40}
41
1class Solution {
2public:
3 bool isValid(string word) {
4 // Check minimum length requirement
5 if (word.size() < 3) {
6 return false;
7 }
8
9 // Initialize flags to track presence of vowels and consonants
10 bool hasVowel = false;
11 bool hasConsonant = false;
12
13 // Create a lookup table for vowels (26 letters, indexed by 'a' to 'z')
14 bool isVowelLookup[26] = {};
15 string vowels = "aeiou";
16
17 // Mark vowel positions in the lookup table
18 for (char c : vowels) {
19 isVowelLookup[c - 'a'] = true;
20 }
21
22 // Iterate through each character in the word
23 for (char c : word) {
24 if (isalpha(c)) {
25 // Convert to lowercase and check if it's a vowel
26 char lowerChar = tolower(c);
27 if (isVowelLookup[lowerChar - 'a']) {
28 hasVowel = true;
29 } else {
30 hasConsonant = true;
31 }
32 } else if (!isdigit(c)) {
33 // If character is neither letter nor digit, word is invalid
34 return false;
35 }
36 // If character is a digit, continue to next character
37 }
38
39 // Word is valid only if it contains at least one vowel and one consonant
40 return hasVowel && hasConsonant;
41 }
42};
43
1/**
2 * Validates if a word meets specific criteria:
3 * - Must be at least 3 characters long
4 * - Must contain only alphanumeric characters
5 * - Must contain at least one vowel
6 * - Must contain at least one consonant
7 * @param word - The word to validate
8 * @returns true if the word is valid, false otherwise
9 */
10function isValid(word: string): boolean {
11 // Check minimum length requirement
12 if (word.length < 3) {
13 return false;
14 }
15
16 // Track whether vowel and consonant are found
17 let hasVowel: boolean = false;
18 let hasConsonant: boolean = false;
19
20 // Define set of vowels (both lowercase and uppercase)
21 const vowels: Set<string> = new Set<string>(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
22
23 // Iterate through each character in the word
24 for (const character of word) {
25 // Check if character is alphanumeric
26 if (!/[a-zA-Z0-9]/.test(character)) {
27 return false;
28 }
29
30 // If character is a letter, check if it's a vowel or consonant
31 if (/[a-zA-Z]/.test(character)) {
32 if (vowels.has(character)) {
33 hasVowel = true;
34 } else {
35 hasConsonant = true;
36 }
37 }
38 }
39
40 // Word is valid only if it contains both vowel and consonant
41 return hasVowel && hasConsonant;
42}
43
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the input string word
. This is because the algorithm iterates through each character in the string exactly once using a single for loop. Within the loop, all operations are constant time: checking if a character is alphanumeric (isalnum()
), checking if it's alphabetic (isalpha()
), and checking membership in the vowel set are all O(1)
operations.
The space complexity is O(1)
. The algorithm uses a fixed amount of extra space regardless of the input size. The vowel set vs
contains exactly 10 characters (the vowels in both lowercase and uppercase), which is a constant. The boolean variables has_vowel
and has_consonant
also use constant space. No additional data structures that scale with the input size are created.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting that digits are neither vowels nor consonants
A common mistake is assuming that if a character is not a vowel, it must be a consonant. This leads to incorrectly counting digits as consonants.
Incorrect approach:
for char in word: if not char.isalnum(): return False if char in vowels: has_vowel = True else: # Wrong! This treats digits as consonants has_consonant = True
Correct approach:
for char in word: if not char.isalnum(): return False if char.isalpha(): # Only check letters for vowel/consonant if char in vowels: has_vowel = True else: has_consonant = True
2. Case sensitivity issues with vowel checking
Developers often forget to check both uppercase and lowercase vowels, leading to words like "ABC" being incorrectly validated.
Incorrect approach:
vowels = set("aeiou") # Missing uppercase vowels
Correct approach:
vowels = set("aeiouAEIOU") # Include both cases
# OR
if char.lower() in "aeiou": # Convert to lowercase for comparison
3. Early return optimization mistake
Some might try to optimize by returning true as soon as both conditions are met, but forget to complete the character validation.
Incorrect approach:
for char in word: if char.isalpha(): if char in vowels: has_vowel = True else: has_consonant = True if has_vowel and has_consonant: return True # Wrong! Haven't checked all characters for validity # Missing check for invalid characters
Correct approach:
for char in word: if not char.isalnum(): return False # Must validate all characters first if char.isalpha(): if char in vowels: has_vowel = True else: has_consonant = True return has_vowel and has_consonant
4. Misunderstanding alphanumeric validation
Using incorrect methods to check for valid characters, such as checking against a predefined string instead of using isalnum()
.
Incorrect approach:
valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" for char in word: if char not in valid_chars: # Inefficient O(n) lookup return False
Correct approach:
for char in word: if not char.isalnum(): # Built-in method, O(1) check return False
What is an advantages of top-down dynamic programming vs bottom-up dynamic programming?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!