22 Jun 2024PHPHard

Strong Password Checker

find minimum steps to make password strong by handling length, character types, and repeating sequences.

handle three cases: too short, too long, just right. for each, count missing character types and repeating sequences. prioritize fixes that solve multiple issues.

for long passwords, use deletions to break repeating sequences efficiently. for short passwords, use insertions. for correct length, use replacements.

requirements

  • length 6-20
  • contains lowercase, uppercase, digit
  • no three consecutive same characters

complexity

O(n) time to scan password and count issues. O(1) space. greedy approach handles all cases.

Solution files

PHPstrong-password-checker/solution.php
class Solution {

function strongPasswordChecker($password) {
    $n = strlen($password);
    
    $hasLower = preg_match(class="syntax-string">'/[a-z]/', $password);
    $hasUpper = preg_match(class="syntax-string">'/[A-Z]/', $password);
    $hasDigit = preg_match(class="syntax-string">'/[class="syntax-number">0-class="syntax-number">9]/', $password);
    
    $missingTypes = class="syntax-number">3 - ($hasLower + $hasUpper + $hasDigit);
    
    $replacements = class="syntax-number">0;
    $oneMod = $twoMod = class="syntax-number">0;
    
    $i = class="syntax-number">2;
    while ($i < $n) {
        if ($password[$i] == $password[$i - class="syntax-number">1] && $password[$i - class="syntax-number">1] == $password[$i - class="syntax-number">2]) {
            $length = class="syntax-number">2;
            while ($i < $n && $password[$i] == $password[$i - class="syntax-number">1]) {
                $length++;
                $i++;
            }
            $replacements += intval($length / class="syntax-number">3);
            if ($length % class="syntax-number">3 == class="syntax-number">0) {
                $oneMod++;
            } elseif ($length % class="syntax-number">3 == class="syntax-number">1) {
                $twoMod++;
            }
        } else {
            $i++;
        }
    }
    
    if ($n < class="syntax-number">6) {
        return max($missingTypes, class="syntax-number">6 - $n);
    } elseif ($n <= class="syntax-number">20) {
        return max($missingTypes, $replacements);
    } else {
        $deletions = $n - class="syntax-number">20;
        
        $replacements -= min($deletions, $oneMod);
        $deletions -= min($deletions, $oneMod);
        
        $replacements -= min(intval($deletions / class="syntax-number">2), $twoMod);
        $deletions -= min(intval($deletions / class="syntax-number">2), $twoMod) * class="syntax-number">2;
        
        $replacements -= intval($deletions / class="syntax-number">3);
        
        return $n - class="syntax-number">20 + max($missingTypes, $replacements);
    }
}
}

$solution = new Solution();
echo $solution->strongPasswordChecker(class="syntax-string">"a") . class="syntax-string">"\n";
echo $solution->strongPasswordChecker(class="syntax-string">"aA1") . class="syntax-string">"\n";
echo $solution->strongPasswordChecker(class="syntax-string">"1337C0d3") . class="syntax-string">"\n";