如果一个密码满足以下所有条件,我们称它是一个 强 密码:
- 它有至少
8
个字符。
- 至少包含 一个小写英文 字母。
- 至少包含 一个大写英文 字母。
- 至少包含 一个数字 。
- 至少包含 一个特殊字符 。特殊字符为:
"!@#%^&*()-+"
中的一个。
- 它 不 包含
2
个连续相同的字符(比方说 "aab"
不符合该条件,但是 "aba"
符合该条件)。
给你一个字符串 password
,如果它是一个 强 密码,返回 true
,否则返回 false
。
示例 1:
**输入:** password = "IloveLe3tcode!"
**输出:** true
**解释:** 密码满足所有的要求,所以我们返回 true 。
示例 2:
**输入:** password = "Me+You--IsMyDream"
**输出:** false
**解释:** 密码不包含数字,且包含 2 个连续相同的字符。所以我们返回 false 。
示例 3:
**输入:** password = "1aB!"
**输出:** false
**解释:** 密码不符合长度要求。所以我们返回 false 。
提示:
1 <= password.length <= 100
password
包含字母,数字和 "!@#%^&*()-+"
这些特殊字符。
方法一:模拟
思路与算法
我们按照题目的要求模拟即可。
对于「它有至少 8 个字符」的要求,我们可以判断给定的字符串 password 的长度是否至少为 8。
对于「至少包含一个小写英文字母、一个大写英文字母、一个数字、一个特殊字符」的要求,我们各自使用一个布尔变量 hasLower}, \textit{hasUpper}, \textit{hasDigit}, \textit{hasSpecial 来进行记录。我们可以对字符串 password 进行一次遍历,如果遇到某一类型的字符,就将对应的布尔变量置为 True。
对于英文字母和数字,我们可以使用语言自带的 API 进行判断,也可以根据它们的 ASCII 码范围进行判断;对于特殊字符,我们可以提前将所有的特殊字符放入一个哈希表中,并判断遍历到的字符是否在哈希表中即可。
对于「不包含 2 个连续相同的字符」的要求,当我们遍历到字符串 password 的第 i 个字符时,如果它和第 i+1 个字符相同,那么我们直接返回 False。
代码
[sol1-C++]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public: bool strongPasswordCheckerII(string password) { if (password.size() < 8) { return false; }
unordered_set<char> specials = {'!', '@', '#', '', '%', '^', '&', '*', '(', ')', '-', '+'}; int n = password.size(); bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false; for (int i = 0; i < n; ++i) { if (i != n - 1 && password[i] == password[i + 1]) { return false; }
char ch = password[i]; if (islower(ch)) { hasLower = true; } else if (isupper(ch)) { hasUpper = true; } else if (isdigit(ch)) { hasDigit = true; } else if (specials.count(ch)) { hasSpecial = true; } }
return hasLower && hasUpper && hasDigit && hasSpecial; } };
|
[sol1-Java]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Solution { public boolean strongPasswordCheckerII(String password) { if (password.length() < 8) { return false; }
Set<Character> specials = new HashSet<Character>() { { add('!'); add('@'); add('#'); add(''); add('%'); add('^'); add('&'); add('*'); add('('); add(')'); add('-'); add('+'); } }; int n = password.length(); boolean hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false; for (int i = 0; i < n; ++i) { if (i != n - 1 && password.charAt(i) == password.charAt(i + 1)) { return false; }
char ch = password.charAt(i); if (Character.isLowerCase(ch)) { hasLower = true; } else if (Character.isUpperCase(ch)) { hasUpper = true; } else if (Character.isDigit(ch)) { hasDigit = true; } else if (specials.contains(ch)) { hasSpecial = true; } }
return hasLower && hasUpper && hasDigit && hasSpecial; } }
|
[sol1-C#]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Solution { public bool StrongPasswordCheckerII(string password) { if (password.Length < 8) { return false; }
ISet<char> specials = new HashSet<char>() {'!', '@', '#', '', '%', '^', '&', '*', '(', ')', '-', '+'}; int n = password.Length; bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false; for (int i = 0; i < n; ++i) { if (i != n - 1 && password[i] == password[i + 1]) { return false; }
char ch = password[i]; if (char.IsLower(ch)) { hasLower = true; } else if (char.IsUpper(ch)) { hasUpper = true; } else if (char.IsDigit(ch)) { hasDigit = true; } else if (specials.Contains(ch)) { hasSpecial = true; } }
return hasLower && hasUpper && hasDigit && hasSpecial; } }
|
[sol1-Python3]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution: def strongPasswordCheckerII(self, password: str) -> bool: if len(password) < 8: return False specials = set("!@#%^&*()-+") hasLower = hasUpper = hasDigit = hasSpecial = False
for i, ch in enumerate(password): if i != len(password) - 1 and password[i] == password[i + 1]: return False
if ch.islower(): hasLower = True elif ch.isupper(): hasUpper = True elif ch.isdigit(): hasDigit = True elif ch in specials: hasSpecial = True
return hasLower and hasUpper and hasDigit and hasSpecial
|
[sol1-C]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| bool strongPasswordCheckerII(char * password) { int n = strlen(password); if (n < 8) { return false; } char *specialChars = "!@#%^&*()-+"; bool specials[128]; memset(specials, 0, sizeof(specials)); for (int i = 0; i < specialChars[i] != '\0'; i++) { specials[specialChars[i]] = true; } bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false; for (int i = 0; i < n; ++i) { if (i != n - 1 && password[i] == password[i + 1]) { return false; }
char ch = password[i]; if (islower(ch)) { hasLower = true; } else if (isupper(ch)) { hasUpper = true; } else if (isdigit(ch)) { hasDigit = true; } else if (specials[ch]) { hasSpecial = true; } } return hasLower && hasUpper && hasDigit && hasSpecial; }
|
[sol1-JavaScript]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| var strongPasswordCheckerII = function(password) { if (password.length < 8) { return false; }
const specials = new Set(); specials.add('!'); specials.add('@'); specials.add('#'); specials.add(''); specials.add('%'); specials.add('^'); specials.add('&'); specials.add('*'); specials.add('('); specials.add(')'); specials.add('-'); specials.add('+'); const n = password.length; let hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false; for (let i = 0; i < n; ++i) { if (i !== n - 1 && password[i] === password[i + 1]) { return false; }
const ch = password[i]; if (isLowerCase(ch)) { hasLower = true; } else if (isUpperCase(ch)) { hasUpper = true; } else if (isDigit(ch)) { hasDigit = true; } else if (specials.has(ch)) { hasSpecial = true; } } return hasLower && hasUpper && hasDigit && hasSpecial; };
const isDigit = (ch) => { return parseFloat(ch).toString() === "NaN" ? false : true; }
const isLowerCase = str => 'a' <= str && str <= 'z';
const isUpperCase = str => 'A' <= str && str <= 'Z';
|
[sol1-Golang]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| func strongPasswordCheckerII(password string) bool { n := len(password) if n < 8 { return false }
var hasLower, hasUpper, hasDigit, hasSpecial bool for i, ch := range password { if i != n-1 && password[i] == password[i+1] { return false } if unicode.IsLower(ch) { hasLower = true } else if unicode.IsUpper(ch) { hasUpper = true } else if unicode.IsDigit(ch) { hasDigit = true } else if strings.ContainsRune("!@#%^&*()-+", ch) { hasSpecial = true } }
return hasLower && hasUpper && hasDigit && hasSpecial }
|
复杂度分析