
3136. Valid Word
Problem Statement
A word is considered valid if:
- It contains at least 3 characters
- It contains only digits (0-9) and English letters (uppercase and lowercase)
- It includes at least one vowel
- It includes at least one consonant
Given a string word
, return true
if word is valid, otherwise return
false
.
- 'a', 'e', 'i', 'o', 'u', and their uppercase versions are vowels
- A consonant is an English letter that is not a vowel
Example 1
Input: word = "234Adas"
Output: true
Explanation: Satisfies all conditions - length > 3, only valid chars, has vowels (A, a) and consonants (d, s)
Example 2
Input: word = "b3"
Output: false
Explanation: Too short (only 2 chars) and missing vowel
Example 3
Input: word = "a3$e"
Output: false
Explanation: Contains invalid character '$' and missing consonant
- 1 <= word.length <=20
- word consists of English uppercase and lowercase letters, digits, '@', '#', and '$'
Key Insights
To solve this problem, we need to verify four conditions:
- Length check: The word must have at least 3 characters
- Character validation: Only digits (0-9) and English letters are allowed
- Vowel presence: At least one vowel must exist in the word
- Consonant presence: At least one consonant must exist in the word
Approach 1: Iterative Check (Optimal)
This approach checks all conditions in a single pass through the string.
Algorithm Steps
- Check if word length is at least 3
- Initialize flags for vowel and consonant presence
- Iterate through each character:
- If character is invalid (not digit, not letter), return false
- For letters: convert to lowercase and check if vowel
- Set vowel/consonant flags accordingly
- After iteration, check all conditions are satisfied
class Solution {
public:
bool isValid(string word) {
if (word.length() < 3) return false;
bool hasVowel = false;
bool hasConsonant = false;
for (char c : word) {
if (isdigit(c)) {
// Digits are always valid but don't affect vowel/consonant checks
continue;
}
else if (isalpha(c)) {
char lowerC = tolower(c);
if (lowerC == 'a' || lowerC == 'e' || lowerC == 'i' || lowerC == 'o' || lowerC == 'u') {
hasVowel = true;
} else {
hasConsonant = true;
}
}
else {
// Invalid character found
return false;
}
}
return hasVowel && hasConsonant;
}
};
class Solution {
public boolean isValid(String word) {
if (word.length() < 3) return false;
boolean hasVowel = false;
boolean hasConsonant = false;
for (char c : word.toCharArray()) {
if (Character.isDigit(c)) {
// Skip digits
continue;
}
else if (Character.isLetter(c)) {
char lowerC = Character.toLowerCase(c);
if (lowerC == 'a' || lowerC == 'e' || lowerC == 'i' || lowerC == 'o' || lowerC == 'u') {
hasVowel = true;
} else {
hasConsonant = true;
}
}
else {
// Invalid character
return false;
}
}
return hasVowel && hasConsonant;
}
}
class Solution:
def isValid(self, word: str) -> bool:
if len(word) < 3:
return False
has_vowel = False
has_consonant = False
vowels = "aeiou"
for char in word:
if char.isdigit():
continue
elif char.isalpha():
lower_char = char.lower()
if lower_char in vowels:
has_vowel = True
else:
has_consonant = True
else:
# Invalid character found
return False
return has_vowel and has_consonant
- Time Complexity: O(n) - Single pass through the string
- Space Complexity: O(1) - Constant space usage
Approach 2: Set-Based Validation
This approach uses sets to track vowels and consonants for improved readability.
#include <unordered_set>
#include <cctype>
class Solution {
public:
bool isValid(string word) {
if (word.size() < 3) return false;
unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};
bool hasVowel = false;
bool hasConsonant = false;
for (char c : word) {
if (isdigit(c)) continue;
if (!isalpha(c)) return false;
char lowerC = tolower(c);
if (vowels.count(lowerC)) {
hasVowel = true;
} else {
hasConsonant = true;
}
}
return hasVowel && hasConsonant;
}
};
import java.util.Set;
import java.util.HashSet;
class Solution {
public boolean isValid(String word) {
if (word.length() < 3) return false;
Set<Character> vowels = new HashSet<>();
vowels.add('a'); vowels.add('e'); vowels.add('i');
vowels.add('o'); vowels.add('u');
boolean hasVowel = false;
boolean hasConsonant = false;
for (char c : word.toCharArray()) {
if (Character.isDigit(c)) continue;
if (!Character.isLetter(c)) return false;
char lowerC = Character.toLowerCase(c);
if (vowels.contains(lowerC)) {
hasVowel = true;
} else {
hasConsonant = true;
}
}
return hasVowel && hasConsonant;
}
}
class Solution:
def isValid(self, word: str) -> bool:
if len(word) < 3:
return False
vowels = {'a', 'e', 'i', 'o', 'u'}
has_vowel = False
has_consonant = False
for char in word:
if char.isdigit():
continue
elif char.isalpha():
lower_char = char.lower()
if lower_char in vowels:
has_vowel = True
else:
has_consonant = True
else:
return False
return has_vowel and has_consonant
Approach 3: Regular Expressions (Python)
This Python-specific approach uses regex for pattern matching and validation.
import re
class Solution:
def isValid(self, word: str) -> bool:
if len(word) < 3:
return False
# Check for invalid characters
if re.search(r'[^a-zA-Z0-9]', word):
return False
# Check for at least one vowel
if not re.search(r'[aeiouAEIOU]', word):
return False
# Check for at least one consonant
if not re.search(r'[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]', word):
return False
return True
Approach Comparison
Approach | Time | Space | Best For |
---|---|---|---|
Iterative Check | O(n) | O(1) | Optimal solution for all languages |
Set-Based | O(n) | O(1) | Improved readability |
Regex (Python) | O(n) | O(1) | Conciseness in Python |
Edge Cases
1. Minimum length requirement
Input: "a1" → Output: false (too short)
2. All digits
Input: "123" → Output: false (no vowels/consonants)
3. Only vowels
Input: "aei" → Output: false (no consonants)
4. Only consonants
Input: "bcdfg" → Output: false (no vowels)
5. Mixed valid characters
Input: "Passw0rd" → Output: true (meets all criteria)
6. Invalid characters
Input: "abc@" → Output: false (invalid character '@')
Frequently Asked Questions
Why are digits allowed if they don't count as vowels or consonants?
Digits are permitted in valid words as per the problem statement, but they don't fulfill the vowel or consonant requirements. The word must contain at least one vowel and one consonant from letters.
How should uppercase vowels be handled?
Uppercase vowels ('A', 'E', etc.) should be treated the same as lowercase vowels. The solution should convert letters to a consistent case before checking.
Can a word be valid if it has vowels but no consonants?
No, the problem requires at least one vowel AND at least one consonant. Words like "aei" would be invalid.
What constitutes an invalid character?
Any character that is not a digit (0-9) and not an English letter (a-z, A-Z). Special characters like '@', '#', and '$' are explicitly invalid.
Is a word with 2 letters and 1 digit considered valid?
No, because it has only 3 characters but lacks both vowel and consonant requirements. The digit doesn't count as either, so it would fail the vowel/consonant checks.
How does the solution handle mixed case words?
By converting all letters to lowercase before checking vowel/consonant status, the solution handles mixed case words consistently.
Can a word be valid with only one vowel and one consonant?
Yes, as long as it has at least 3 characters and meets all other requirements. For example, "a1b" would be valid.
Why is the iterative approach more efficient than regex?
The iterative approach processes the string in a single pass with O(n) time complexity and minimal overhead, while regex operations often have higher constant factors.
What's the best approach for very long strings?
For this problem, strings are constrained to 20 characters, so all approaches are efficient. For longer strings, the iterative approach would be preferred.
How would you modify the solution to count 'y' as a vowel?
Simply add 'y' to the vowel set/check:
if (lowerC == 'a' || lowerC == 'e' || ... || lowerC == 'y')