Strong Password Checker II
EASYDescription
A password is said to be strong if it satisfies all the following criteria:
- It has at least
8characters. - 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 special character. The special characters are the characters in the following string:
"!@#$%^&*()-+". - It does not contain
2of the same character in adjacent positions (i.e.,"aab"violates this condition, but"aba"does not).
Given a string password, return true if it is a strong password. Otherwise, return false.
Example 1:
Input: password = "IloveLe3tcode!" Output: true Explanation: The password meets all the requirements. Therefore, we return true.
Example 2:
Input: password = "Me+You--IsMyDream" Output: false Explanation: The password does not contain a digit and also contains 2 of the same character in adjacent positions. Therefore, we return false.
Example 3:
Input: password = "1aB!" Output: false Explanation: The password does not meet the length requirement. Therefore, we return false.
Constraints:
1 <= password.length <= 100passwordconsists of letters, digits, and special characters:"!@#$%^&*()-+".
Approaches
Checkout 2 different approaches to solve Strong Password Checker II. Click on different approaches to view the approach and algorithm in detail.
Regular Expression Matching
This approach uses regular expressions (regex) to validate most of the password criteria. Regular expressions provide a powerful and declarative way to define patterns for string matching. However, for this specific problem, checking for adjacent identical characters is cumbersome with regex, so a separate loop is still needed for that condition.
Algorithm
- Check if
password.length()is less than 8. If so, returnfalse. - Iterate from the first to the second-to-last character of the password. In each iteration, check if
password.charAt(i)is equal topassword.charAt(i + 1). If they are equal, returnfalse. - Use the regex pattern
.*[a-z].*to check for the presence of a lowercase letter. If not found, returnfalse. - Use the regex pattern
.*[A-Z].*to check for the presence of an uppercase letter. If not found, returnfalse. - Use the regex pattern
.*\\d.*to check for the presence of a digit. If not found, returnfalse. - Use the regex pattern
.*[!@#$%^&*()+-].*to check for the presence of a special character. If not found, returnfalse. - If all checks pass, return
true.
The overall logic is to check each of the six conditions.
- Length Check: First, we verify if the password's length is at least 8. If not, we immediately return
false. - Adjacent Character Check: We iterate through the password string with a simple loop to ensure no two adjacent characters are the same. This is easier to do with a loop than with a complex negative lookahead in regex. If we find a pair, we return
false. - Character Type Checks: For the remaining four conditions (presence of lowercase, uppercase, digit, and special character), we use separate regex patterns.
.*[a-z].*checks for at least one lowercase letter..*[A-Z].*checks for at least one uppercase letter..*\\d.*checks for at least one digit..*[!@#$%^&*()+-].*checks for at least one special character. We compile each pattern and match it against the password. The final result istrueonly if all these checks pass.
import java.util.regex.Pattern;
class Solution {
public boolean strongPasswordCheckerII(String password) {
if (password.length() < 8) {
return false;
}
// Check for adjacent identical characters
for (int i = 0; i < password.length() - 1; i++) {
if (password.charAt(i) == password.charAt(i + 1)) {
return false;
}
}
// Regex for character types
boolean hasLower = Pattern.compile(".*[a-z].*").matcher(password).matches();
if (!hasLower) return false;
boolean hasUpper = Pattern.compile(".*[A-Z].*").matcher(password).matches();
if (!hasUpper) return false;
boolean hasDigit = Pattern.compile(".*\\d.*").matcher(password).matches();
if (!hasDigit) return false;
// Note: Hyphen '-' needs to be escaped or placed at the end inside []
boolean hasSpecial = Pattern.compile(".*[!@#$%^&*()+-].*").matcher(password).matches();
if (!hasSpecial) return false;
return true;
}
}
Complexity Analysis
Pros and Cons
- Code can be concise and declarative for the character type checks.
- Generally slower than a manual single-pass loop due to the overhead of compiling and executing regular expressions.
- The check for adjacent characters doesn't fit neatly into the regex approach, requiring a separate loop.
- Regex patterns can be less readable for developers not familiar with them.
Code Solutions
Checking out 3 solutions in different languages for Strong Password Checker II. Click on different languages to view the code.
class Solution {
public
boolean strongPasswordCheckerII(String password) {
if (password.length() < 8) {
return false;
}
int mask = 0;
for (int i = 0; i < password.length(); ++i) {
char c = password.charAt(i);
if (i > 0 && c == password.charAt(i - 1)) {
return false;
}
if (Character.isLowerCase(c)) {
mask |= 1;
} else if (Character.isUpperCase(c)) {
mask |= 2;
} else if (Character.isDigit(c)) {
mask |= 4;
} else {
mask |= 8;
}
}
return mask == 15;
}
}
Video Solution
Watch the video walkthrough for Strong Password Checker II
Similar Questions
5 related questions you might find useful
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.