Skip to main content
Back to problems
#420
Hard Algorithms

Strong password checker

String Greedy Heap (Priority Queue)
15.5% acceptance
Jan 13, 2026
961
1753
A password is considered strong if the below conditions are all met: It has at least 6 characters and at most 20 characters. It contains at least one lowercase letter, at least one uppercase letter, and at least one digit. It does not contain three repeating characters in a row (i.e., "Baaabb0" is weak, but "Baaba0" is strong). Given a string password, return the minimum number of steps required to make password strong. if password is already strong, return 0. In one step, you can: Insert one character to password, Delete one character from password, or Replace one character of password with another character.

Solution

Rust
Time O(n²)
Space O(1)
LeetCode
solution.rs
impl Solution {
  pub fn strong_password_checker(password: String) -> i32 {
    let n = password.len();
    let bytes = password.as_bytes();
    let mut has_lower = false;
    let mut has_upper = false;
    let mut has_digit = false;
    
    for &ch in bytes {
      if ch >= b'a' && ch <= b'z' { has_lower = true; }
      else if ch >= b'A' && ch <= b'Z' { has_upper = true; }
      else if ch >= b'0' && ch <= b'9' { has_digit = true; }
    }
    
    let missing_types = (!has_lower as i32) + (!has_upper as i32) + (!has_digit as i32);
    
    if n < 6 {
      return missing_types.max(6 - n as i32);
    }
    
    let mut replace = 0;
    let mut one_seq = 0;
    let mut two_seq = 0;
    let mut i = 2;
    
    while i < n {
      if bytes[i] == bytes[i - 1] && bytes[i - 1] == bytes[i - 2] {
        let mut length = 2;
        while i < n && bytes[i] == bytes[i - 1] {
          length += 1;
          i += 1;
        }
        replace += length / 3;
        match length % 3 {
          0 => one_seq += 1,
          1 => two_seq += 1,
          _ => {}
        }
      } else {
        i += 1;
      }
    }
    
    if n <= 20 {
      return replace.max(missing_types);
    }
    
    let delete = (n - 20) as i32;
    
    // Optimize deletions to reduce replacements efficiently
    let one_del = delete.min(one_seq);
    replace -= one_del;
    
    let two_del = (delete - one_del).min(two_seq * 2) / 2;
    replace -= two_del;
    
    let three_del = (delete - one_del - two_del * 2) / 3;
    replace -= three_del;
    
    delete + replace.max(missing_types)
  }
}