2
private static final int MIN_LENGTH = 6;3
private static final int MAX_LENGTH = 20;5
public int strongPasswordChecker(String password) {6
int numMissingComponents = getNumberOfMissingComponents(password);7
int n = password.length();10
return Math.max(numMissingComponents, MIN_LENGTH - n);13
List<Integer> repeats = buildRepeatList(password);15
int over = Math.max(0, n - MAX_LENGTH);16
int numRemoval = over;18
// use overage for repeat % 3 == 0 case. One removal would reduce one replacement19
for (int i = 0; i < repeats.size() && over > 0; i++) {20
int repeat = repeats.get(i);21
if (repeat >= 3 && repeat % 3 == 0) {22
repeats.set(i, repeat - 1);26
// use overage for repeat % 3 == 1 case. Two removal would reduce one replacement27
for (int i = 0; i < repeats.size() && over > 0; i++) {28
int repeat = repeats.get(i);29
if (repeat >= 3 && repeat % 3 == 1) {30
repeats.set(i, repeat - Math.min(over, 2));31
over -= Math.min(over, 2);36
for (int repeat : repeats) {37
if (over > 0 && repeat >= 3) {38
int reduce = Math.min(over, repeat - 2);43
numReplace += repeat / 3;47
return Math.max(numReplace, numMissingComponents) + numRemoval;50
private List<Integer> buildRepeatList(String password) {51
List<Integer> repeats = new ArrayList<>();52
for (int i = 0; i < password.length(); i++) {53
if (i == 0 || password.charAt(i) != password.charAt(i - 1)) {56
int last = repeats.size() - 1;57
repeats.set(last, repeats.get(last) + 1);63
private int getNumberOfMissingComponents(String password) {67
for (char c : password.toCharArray()) {68
if (Character.isDigit(c)) {71
if (Character.isLowerCase(c)) {74
if (Character.isUpperCase(c)) {78
return digit + upper + lower;