Problem

A password is said to be strong if it satisfies all the following criteria:

  • It has at least 8 characters.
  • 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 2 of 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 astrong password. Otherwise, return false.

Examples

Example 1

1
2
3
Input: password = "IloveLe3tcode!"
Output: true
Explanation: The password meets all the requirements. Therefore, we return true.

Example 2

1
2
3
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

1
2
3
Input: password = "1aB!"
Output: false
Explanation: The password does not meet the length requirement. Therefore, we return false.

Constraints

  • 1 <= password.length <= 100
  • password consists of letters, digits, and special characters: "!@#$%^&*()-+".

Solution

Method 1 - Check All Criteria in One Pass

Intuition

We need to check all the password requirements in a single pass: length, lowercase, uppercase, digit, special character, and no adjacent duplicates.

Approach

  1. Check if the length is at least 8.
  2. Iterate through the password, checking for each required character type and adjacent duplicates.
  3. Return true if all criteria are met, false otherwise.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <string>
using namespace std;
class Solution {
public:
    bool strongPasswordCheckerII(string password) {
        if (password.size() < 8) return false;
        bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;
        string special = "!@#$%^&*()-+";
        for (int i = 0; i < password.size(); ++i) {
            char c = password[i];
            if (i > 0 && c == password[i-1]) return false;
            if (islower(c)) hasLower = true;
            if (isupper(c)) hasUpper = true;
            if (isdigit(c)) hasDigit = true;
            if (special.find(c) != string::npos) hasSpecial = true;
        }
        return hasLower && hasUpper && hasDigit && hasSpecial;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func strongPasswordCheckerII(password string) bool {
    if len(password) < 8 { return false }
    hasLower, hasUpper, hasDigit, hasSpecial := false, false, false, false
    special := "!@#$%^&*()-+"
    for i, c := range password {
        if i > 0 && password[i] == password[i-1] { return false }
        switch {
        case c >= 'a' && c <= 'z': hasLower = true
        case c >= 'A' && c <= 'Z': hasUpper = true
        case c >= '0' && c <= '9': hasDigit = true
        case strings.ContainsRune(special, c): hasSpecial = true
        }
    }
    return hasLower && hasUpper && hasDigit && hasSpecial
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution {
    public boolean strongPasswordCheckerII(String password) {
        if (password.length() < 8) return false;
        boolean hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;
        String special = "!@#$%^&*()-+";
        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)) hasLower = true;
            if (Character.isUpperCase(c)) hasUpper = true;
            if (Character.isDigit(c)) hasDigit = true;
            if (special.indexOf(c) != -1) hasSpecial = true;
        }
        return hasLower && hasUpper && hasDigit && hasSpecial;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
fun strongPasswordCheckerII(password: String): Boolean {
    if (password.length < 8) return false
    val special = "!@#$%^&*()-+"
    var hasLower = false; var hasUpper = false; var hasDigit = false; var hasSpecial = false
    for (i in password.indices) {
        val c = password[i]
        if (i > 0 && c == password[i-1]) return false
        if (c.isLowerCase()) hasLower = true
        if (c.isUpperCase()) hasUpper = true
        if (c.isDigit()) hasDigit = true
        if (special.contains(c)) hasSpecial = true
    }
    return hasLower && hasUpper && hasDigit && hasSpecial
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def strongPasswordCheckerII(password: str) -> bool:
    if len(password) < 8:
        return False
    has_lower = has_upper = has_digit = has_special = False
    special = set("!@#$%^&*()-+")
    for i, c in enumerate(password):
        if i > 0 and c == password[i-1]:
            return False
        if c.islower(): has_lower = True
        if c.isupper(): has_upper = True
        if c.isdigit(): has_digit = True
        if c in special: has_special = True
    return has_lower and has_upper and has_digit and has_special
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
pub fn strong_password_checker_ii(password: String) -> bool {
    if password.len() < 8 { return false; }
    let special = "!@#$%^&*()-+";
    let mut has_lower = false;
    let mut has_upper = false;
    let mut has_digit = false;
    let mut has_special = false;
    let bytes = password.as_bytes();
    for i in 0..bytes.len() {
        let c = bytes[i] as char;
        if i > 0 && bytes[i] == bytes[i-1] { return false; }
        if c.is_ascii_lowercase() { has_lower = true; }
        if c.is_ascii_uppercase() { has_upper = true; }
        if c.is_ascii_digit() { has_digit = true; }
        if special.contains(c) { has_special = true; }
    }
    has_lower && has_upper && has_digit && has_special
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function strongPasswordCheckerII(password: string): boolean {
    if (password.length < 8) return false;
    const special = "!@#$%^&*()-+";
    let hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;
    for (let i = 0; i < password.length; i++) {
        const c = password[i];
        if (i > 0 && c === password[i-1]) return false;
        if (c >= 'a' && c <= 'z') hasLower = true;
        if (c >= 'A' && c <= 'Z') hasUpper = true;
        if (c >= '0' && c <= '9') hasDigit = true;
        if (special.includes(c)) hasSpecial = true;
    }
    return hasLower && hasUpper && hasDigit && hasSpecial;
}

Complexity

  • ⏰ Time complexity: O(n)
  • 🧺 Space complexity: O(1)