一个强密码应满足以下所有条件:
- 由至少6个,至多20个字符组成。
- 至少包含一个小写字母,一个大写字母,和一个数字。
- 同一字符不能连续出现三次 (比如 "...aaa..." 是不允许的, 但是 "...aa...a..." 是可以的)。
编写函数 strongPasswordChecker(s),s 代表输入字符串,如果 s 已经符合强密码条件,则返回0;否则返回要将 s 修改为满足强密码条件的字符串所需要进行修改的最小步数。
插入、删除、替换任一字符都算作一次修改。
class Solution {
public:
int strongPasswordChecker(string s) {
int deleteTarget = max(0, (int)s.length() - 20), addTarget = max(0, 6 - (int)s.length());
int toDelete = 0, toAdd = 0, toReplace = 0, needUpper = 1, needLower = 1, needDigit = 1;
for (int l = 0, r = 0; r < s.length(); r++) {
if (isupper(s[r])) { needUpper = 0; }
if (islower(s[r])) { needLower = 0; }
if (isdigit(s[r])) { needDigit = 0; }
if (r - l == 2) {
if (s[l] == s[l + 1] && s[l + 1] == s[r]) {
if (toAdd < addTarget) { toAdd++, l = r; }
else { toReplace++, l = r + 1; }
} else { l++; }
}
}
if (s.length() <= 20) { return max(addTarget + toReplace, needUpper + needLower + needDigit); }
toReplace = 0;
vector<unordered_map<int, int>> lenCnts(3);
for (int l = 0, r = 0, len; r <= s.length(); r++) {
if (r == s.length() || s[l] != s[r]) {
if ((len = r - l) > 2) { lenCnts[len % 3][len]++; }
l = r;
}
}
for (int i = 0, numLetters, dec; i < 3; i++) {
for (auto it = lenCnts[i].begin(); it != lenCnts[i].end(); it++) {
if (i < 2) {
numLetters = i + 1, dec = min(it->second, (deleteTarget - toDelete) / numLetters);
toDelete += dec * numLetters, it->second -= dec;
if (it->first - numLetters > 2) { lenCnts[2][it->first - numLetters] += dec; }
}
toReplace += (it->second) * ((it->first) / 3);
}
}
int dec = (deleteTarget - toDelete) / 3;
toReplace -= dec, toDelete -= dec * 3;
return deleteTarget + max(toReplace, needUpper + needLower + needDigit);
}
};