【Leetcode】3136. 有效单词
文章目录
- 题目
- 题目描述
- 思路
- 方法一:遍历计数法
- 方法二:正则表达式法
- 代码
- C++
- 方法一:遍历计数法
- 方法二:正则表达式法
- Java
- 方法一:遍历计数法
- 方法二:正则表达式法
- Python
- 方法一:遍历计数法
- 方法二:正则表达式法
- 复杂度分析
- 时间复杂度
- 空间复杂度
- 结果
- 总结
题目
LeetCode 3136. 有效单词
题目描述
有效单词需要满足以下几个条件:
- 至少包含3个字符
- 由数字0-9和英文大小写字母组成(不必包含所有这类字符)
- 至少包含一个元音字母
- 至少包含一个辅音字母
给你一个字符串word,如果word是一个有效单词,则返回true,否则返回false。
注意:
- ‘a’、‘e’、‘i’、‘o’、‘u’ 及其大写形式都属于元音字母
- 英文中的辅音字母是指那些除元音字母之外的字母
思路
这道题可以用两种方法来解决:
方法一:遍历计数法
- 首先检查字符串长度是否至少为3
- 遍历字符串的每个字符:
- 如果遇到非法字符(@、#、$),直接返回false
- 统计元音字母和辅音字母的数量
- 最后检查是否至少有1个元音字母和1个辅音字母
方法二:正则表达式法
使用正则表达式一次性检查所有条件:
(?=.*[aeiouAEIOU])- 先行断言:至少包含一个元音字母(?=.*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])- 先行断言:至少包含一个辅音字母[a-zA-Z0-9]{3,}- 只包含字母和数字,且长度至少为3
代码
C++
方法一:遍历计数法
class Solution {
public:bool isValid(string word) {// 检查长度if (word.length() < 3) {return false;}bool hasVowel = false;bool hasConsonant = false;string vowels = "aeiouAEIOU";for (char c : word) {// 检查是否为非法字符if (c == '@' || c == '#' || c == '$') {return false;}// 检查是否为元音if (vowels.find(c) != string::npos) {hasVowel = true;}// 检查是否为辅音(字母但不是元音)else if (isalpha(c)) {hasConsonant = true;}}return hasVowel && hasConsonant;}
};
方法二:正则表达式法
#include <regex>class Solution {
public:bool isValid(string word) {// 使用正则表达式一次性检查所有条件regex pattern("^(?=.*[aeiouAEIOU])(?=.*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])[a-zA-Z0-9]{3,}$");return regex_match(word, pattern);}
};
Java
方法一:遍历计数法
class Solution {public boolean isValid(String word) {// 检查长度if (word.length() < 3) {return false;}boolean hasVowel = false;boolean hasConsonant = false;String vowels = "aeiouAEIOU";for (char c : word.toCharArray()) {// 检查非法字符if (c == '@' || c == '#' || c == '$') {return false;}// 检查元音if (vowels.indexOf(c) != -1) {hasVowel = true;}// 检查辅音else if (Character.isLetter(c)) {hasConsonant = true;}}return hasVowel && hasConsonant;}
}
方法二:正则表达式法
class Solution {public boolean isValid(String word) {// 使用正则表达式一次性检查所有条件String regex = "^(?=.*[aeiouAEIOU])(?=.*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])[a-zA-Z0-9]{3,}$";return word.matches(regex);}
}
Python
方法一:遍历计数法
class Solution:def isValid(self, word: str) -> bool:# 检查长度if len(word) < 3:return Falsehas_vowel = Falsehas_consonant = Falsevowels = "aeiouAEIOU"for char in word:# 检查非法字符if char in "@#$":return False# 检查元音if char in vowels:has_vowel = True# 检查辅音elif char.isalpha():has_consonant = Truereturn has_vowel and has_consonant
方法二:正则表达式法
import reclass Solution:def isValid(self, word: str) -> bool:# 使用正则表达式一次性检查所有条件pattern = r"^(?=.*[aeiouAEIOU])(?=.*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])[a-zA-Z0-9]{3,}$"return bool(re.match(pattern, word))
复杂度分析
时间复杂度
- 方法一(遍历计数法): O(n),其中n是字符串的长度。需要遍历字符串一次。
- 方法二(正则表达式法): O(n),正则表达式匹配的时间复杂度也是O(n)。
空间复杂度
- 方法一: O(1),只使用了常数个变量来存储状态。
- 方法二: O(1),正则表达式编译后占用常数空间。
结果
以上两种方法都能正确解决问题,在LeetCode上的表现:
- 遍历计数法:更直观,易于理解和调试
- 正则表达式法:代码更简洁,但需要掌握正则表达式语法
总结
这道题考查的是字符串处理和条件判断。两种解法各有优势:
- 遍历计数法:逻辑清晰,容易理解,适合在面试中使用
- 正则表达式法:代码简洁,但需要较好的正则表达式基础
建议在实际开发中根据团队的技术栈和维护性要求选择合适的方法。对于这类字符串验证问题,遍历法通常是更安全和可维护的选择。