A password is considered strong if below conditions are all met:
- It has at least 6 characters and at most 20 characters.
- It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit.
- It must NOT contain three repeating characters in a row ("...aaa..." is weak, but "...aa...a..." is strong, assuming other conditions are met).
Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0.
Insertion, deletion or replace of any one character are all considered as one change.
思路:小于6的情况可以简单求得,关键在于大于20,并有多个重复的情况。需要把重复子串数量存储起来。观察可得,当大于20时,删除操作优先作用于重复个数%3==0子串的情况,再是%3==1子串的情况,再是%3==2子串的情况,(以上操作基于贪心思想,为了之后的替换操作最少)。
class Solution {
public int strongPasswordChecker(String s) {
int len=s.length();
if(len<=3) return 6-len;
boolean f1=false,f2=false,f3=false;
List<Integer> rec=new ArrayList<>();
int remain=s.length()-20;//还能删除的个数
int re=remain;
for(int i=0;i<len;i++){
if('0'<=s.charAt(i)&&s.charAt(i)<='9') f1=true;
if('a'<=s.charAt(i)&&s.charAt(i)<='z') f2=true;
if('A'<=s.charAt(i)&&s.charAt(i)<='Z') f3=true;
int cnt=1;
while(i<s.length()-1&&s.charAt(i)==s.charAt(i+1)){
cnt++;
i++;
}
if(cnt>=3){
if(remain>0){
if(cnt%3==0){
cnt--;
remain--;
}
}
if(cnt>=3)rec.add(cnt);
}
}
int c=3;
if(f1) c--;
if(f2) c--;
if(f3) c--;
if(s.length()==4) return Math.max(2,c);
if(s.length()==5) return Math.max(1,c);
//检查重复,先删除,后替换
for(int i=0;i<rec.size();i++){ //%3=1
if(remain==1){
remain=0;
break;
}
if(remain>0&&rec.get(i)%3==1){
int n=rec.get(i);
rec.set(i,n-2);
remain-=2;
}
}
for(int i=0;i<rec.size();i++){ //%3=2
if(remain==2||remain==1){
remain=0;
break;
}
if(remain>0){
int n=rec.get(i);
if(n>3){
int r=n-2;
rec.set(i,n-Math.min(remain,r));
remain=Math.max(remain-r,0);
}
}
}
int res=re-remain;
if(remain>0) return res+c+remain;//删除余下的
for(int a:rec){//替换
res+=a/3;
c-=a/3;
}
return res+(c>0?c:0);
}
}