Strong Password Checker
Problem Description
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.
Examples
Example 1:
Input: password = "a"
Output: 5
Explanation: The password needs additional characters, an uppercase letter, and a digit to meet the criteria.
Example 2:
Input: password = "aA1"
Output: 3
Explanation: The password needs more characters to reach the minimum length of 6.
Constraints
1 <= password.length <= 50
password
consists of letters, digits, dot'.'
or exclamation mark'!'
.
Solution for Strong Password Checker
Approach
- A strong password should contain at least one lowercase letter, one uppercase letter, and one number.
- It should avoid having the same character repeated three times consecutively and be between 6 and 20 characters long.
The code achieves this by following these steps:
- Utilizes a “requirements” checklist to keep track of the first three criteria (initially unchecked).
- Maintains a record of character repetitions.
- Examines each character in the text:
- If different from the previous character, checks off requirements if not met.
- If the same as the previous character, counts consecutive repetitions.
- Sorts the repeated characters list by the number of repetitions.
- Adjusts the text:
- For text longer than 20 characters, removes one repeated character in sequences of three or more.
- For texts without such sequences, removes one character from the repeated character list.
- Continues until the text is 20 characters or less.
- Calculates the number of characters needed to make the text at least 6 characters long (if it’s shorter).
- Totals all the changes made to meet the rules, providing the minimum number of changes required to create a strong password.
Code in Different Languages
- C++
- Java
- Python
class Solution {
public:
int strongPasswordChecker(string s) {
bitset<3> requirements{111};
list<int> repeats;
auto it = s.begin();
auto it2 = s.end();
while (it != s.end()) {
if (*it != *it2) {
if (requirements.test(0) && islower(*it))
requirements.reset(0);
if (requirements.test(1) && isupper(*it))
requirements.reset(1);
if (requirements.test(2) && isdigit(*it))
requirements.reset(2);
} else {
while (it != s.end() && *it == *it2)
++it;
if (distance(it2, it) != 2)
repeats.push_back(distance(it2, it));
if (it != s.end())
continue;
else
break;
}
it2 = it;
++it;
}
repeats.sort([](const int &lhs, const int &rhs) { return (lhs % 3) < (rhs % 3); });
int ans{0}, len{static_cast<int>(s.size())};
while (len > 20) {
if (!repeats.empty()) {
if (repeats.front() == 3) {
repeats.pop_front();
}
else {
--repeats.front();
repeats.sort([](const int &lhs, const int &rhs) { return (lhs % 3) < (rhs % 3); });
}
++ans;
--len;
}
else {
ans += len - 20;
len = 20;
}
}
int rep_ins{0};
while (!repeats.empty()) {
rep_ins += repeats.front() / 3;
repeats.pop_front();
}
if ((len + rep_ins) < 6) {
rep_ins += 6 - len - rep_ins;
}
ans += max(static_cast<int>(requirements.count()), rep_ins);
return ans;
}
};
class Solution {
public int strongPasswordChecker(String s) {
int res = 0, a = 1, A = 1, d = 1;
char[] carr = s.toCharArray();
int[] arr = new int[carr.length];
for (int i = 0; i < arr.length;) {
if (Character.isLowerCase(carr[i])) a = 0;
if (Character.isUpperCase(carr[i])) A = 0;
if (Character.isDigit(carr[i])) d = 0;
int j = i;
while (i < carr.length && carr[i] == carr[j]) i++;
arr[j] = i - j;
}
int total_missing = (a + A + d);
if (arr.length < 6) {
res += total_missing + Math.max(0, 6 - (arr.length + total_missing));
} else {
int over_len = Math.max(arr.length - 20, 0), left_over = 0;
res += over_len;
for (int k = 1; k < 3; k++) {
for (int i = 0; i < arr.length && over_len > 0; i++) {
if (arr[i] < 3 || arr[i] % 3 != (k - 1)) continue;
arr[i] -= Math.min(over_len, k);
over_len -= k;
}
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= 3 && over_len > 0) {
int need = arr[i] - 2;
arr[i] -= over_len;
over_len -= need;
}
if (arr[i] >= 3) left_over += arr[i] / 3;
}
res += Math.max(total_missing, left_over);
}
return res;
}
}
class Solution(object):
def strongPasswordChecker(self, s):
missing_type = 3
if any('a' <= c <= 'z' for c in s): missing_type -= 1
if any('A' <= c <= 'Z' for c in s): missing_type -= 1
if any(c.isdigit() for c in s): missing_type -= 1
change = 0
one = 0
two = 0
p = 2
while p < len(s):
if s[p] == s[p-1] == s[p-2]:
length = 2
while p < len(s) and s[p] == s[p-1]:
length += 1
p += 1
change += length // 3
if length % 3 == 0: one += 1
elif length % 3 == 1: two += 1
else:
p += 1
if len(s) < 6:
return max(missing_type, 6 - len(s))
elif len(s) <= 20:
return max(missing_type, change)
else:
delete = len(s) - 20
change -= min(delete, one)
change -= min(max(delete - one, 0), two * 2) // 2
change -= max(delete - one - 2 * two, 0) // 3
return delete + max(missing_type, change)
Complexity Analysis
Time Complexity:
Reason: The code iterates through the input string once and performs various operations such as checking character types, counting repeated characters, and maintaining a list of repeats.
Space Complexity:
Reason: The space complexity is linear because the size of the repeats list is proportional to the length of the input
References
-
LeetCode Problem: Strong Password Checker
-
Solution Link: Strong Password Checker
Authors:
Loading...