Strong Password Checker II — Easy Problem & Solution
A password is strong when all of the following hold: it is at least 8 characters long; it contains at least one lowercase letter; it contains at least one…
- Difficulty: Easy
- Topics: Strings
- Asked at: Amazon, Google, TCS
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
A password is strong when all of the following hold:
- it is at least 8 characters long;
- it contains at least one lowercase letter;
- it contains at least one uppercase letter;
- it contains at least one digit;
- it contains at least one of
!@#$%^&*()-+; - it contains no two adjacent equal characters.
Return true if password is strong.
Example 1
Input: password = "CodeKairo#1"
Output: true
Explanation: Long enough, all four character classes, and no repeated neighbours.
Example 2
Input: password = "Coode#1Kairo"
Output: false
Explanation: The `oo` in `Coode` breaks the adjacency rule.
Example 3
Input: password = "Me+You--IsMyDream"
Output: false
Explanation: No digit, and `--` repeats.
Constraints
1 <= password.length <= 100password consists of letters, digits, and characters in "!@#$%^&*()-+".
How to solve Strong Password Checker II
One pass. Reject short passwords up front, then for each character update the four class flags and compare it with the one before it.
Approach
- If the length is under 8, return false.
- For each index, return false if the character equals its predecessor.
- Set the lowercase/uppercase/digit/special flag according to the character's class.
- Return the conjunction of the four flags.
Why it works
The adjacency rule is the only one that can fail early and is worth short-circuiting on; the four class flags can only ever turn on, so they are safe to accumulate and test at the end. Checking the classes with separate scans would be four passes for no gain.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- Adjacent equality applies to any character, digits and specials included, not just letters.
- Exactly 8 characters is long enough — the bound is inclusive.
- The special set is fixed; characters outside it satisfy no class at all.
Reference solution
Python
def strongPasswordCheckerII(password: str) -> bool:
if len(password) < 8:
return False
special = "!@#$%^&*()-+"
lower = upper = digit = spec = False
for i, c in enumerate(password):
if i > 0 and c == password[i - 1]:
return False
if c.islower():
lower = True
elif c.isupper():
upper = True
elif c.isdigit():
digit = True
elif c in special:
spec = True
return lower and upper and digit and specJavaScript
var strongPasswordCheckerII = function(password) {
if (password.length < 8) return false;
var SPECIAL = "!@#$%^&*()-+";
var lower = false, upper = false, digit = false, special = false;
for (var i = 0; i < password.length; i++) {
var c = password.charAt(i);
if (i > 0 && c === password.charAt(i - 1)) return false;
if (c >= "a" && c <= "z") lower = true;
else if (c >= "A" && c <= "Z") upper = true;
else if (c >= "0" && c <= "9") digit = true;
else if (SPECIAL.indexOf(c) !== -1) special = true;
}
return lower && upper && digit && special;
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.