Valid Word Visualization

3136. Valid Word

Difficulty: Easy
Topics: String Validation, Character Classification
Companies: Google, Amazon, Microsoft

Problem Statement

A word is considered valid if:

  1. It contains at least 3 characters
  2. It contains only digits (0-9) and English letters (uppercase and lowercase)
  3. It includes at least one vowel
  4. It includes at least one consonant

Given a string word, return true if word is valid, otherwise return false.

Notes:

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
Constraints:

Key Insights

To solve this problem, we need to verify four conditions:

  1. Length check: The word must have at least 3 characters
  2. Character validation: Only digits (0-9) and English letters are allowed
  3. Vowel presence: At least one vowel must exist in the word
  4. Consonant presence: At least one consonant must exist in the word
Important Note: Digits are allowed in the word but they don't count as vowels or consonants. Only letters are considered for vowel/consonant checks.

Approach 1: Iterative Check (Optimal)

This approach checks all conditions in a single pass through the string.

Algorithm Steps

  1. Check if word length is at least 3
  2. Initialize flags for vowel and consonant presence
  3. 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
  4. After iteration, check all conditions are satisfied
Optimal Solution
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
Complexity Analysis:
  • 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.

Set-Based Solution
#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
Advantage: More readable and maintainable when dealing with multiple vowels

Approach 3: Regular Expressions (Python)

This Python-specific approach uses regex for pattern matching and validation.

Regex Solution (Python)
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
Note: While concise, regex solutions can be less efficient for small strings and harder to maintain for complex patterns.

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
Recommendation: The iterative check is the most efficient and language-agnostic solution

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 '@')
Important: Digits are allowed but don't count toward vowel/consonant requirements

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')

Final Recommendation: The iterative approach provides the best balance of efficiency, readability, and language compatibility for this problem.