A password is considered strong if below conditions are all 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.
题目检测一个字符串变换成强口令需要的最少操作。
这里有3个检测条件。
所以我们可以先执行替换操作。使得字符串满足条件3。
然后分情况讨论:
最后我们还需要检测插入+替换的操作次数是否大于缺少的字符类型。最终得到最少需要操作的次数。复杂度O(n)。代码如下:
/*
*@Auth PalaidnDu
*/
int max(int i1, int i2){
return i1 > i2 ? i1 : i2;
}
int strongPasswordChecker(char * s){
if(*s == '\0'){
return 6;
}
int strLen = 0;
//计算用了几种字符
int useCharType = 0;
int charTypeMap[256] = {0};
int charTypeUse[4] = {0};
for(int i = '0' ;i <= '9' ; ++i){
charTypeMap[i] = 1;
}
for(int i = 'a' ; i <= 'z'; ++i){
charTypeMap[i] = 2;
}
for(int i = 'A' ; i <= 'Z'; ++i){
charTypeMap[i] = 3;
}
int needReplaceCharCount = 0;//需要replace的字符数
int twoDelReplaceCount = 0; //替换replace操作只需要一个del的个数
int onDelReplaceCount = 0;//替换replace操作需要两个del的个数
char* p = s;//用于计算重复字符的长度
char* start = s;//缓存s的开始,用于机选s的长度
while(true){
char c = *s;
charTypeUse[charTypeMap[c]] = 1;//使用了这种类型的字符
if(c != *p){//字符变化了
int containCharLen = s - p;
p = s;
if(containCharLen >= 3){
needReplaceCharCount += containCharLen/3;
if(containCharLen%3==1){//需要两个del消除这个replace
++twoDelReplaceCount;
}else if(containCharLen%3==0){//需要1个del消除这个replace
++onDelReplaceCount;
}
}
}
if(c == '\0'){
break;
}
++s;
}
strLen = s - start;
int withoutCharTypeCount = 0;//缺失的类型
for(int i = 1; i <=3 ; ++i){//统计需要添加多少种字符
if(charTypeUse[i] == 0){
++withoutCharTypeCount;
}
}
if(strLen < 6){//总是只执行insert 和 replace操作
int needInsertCharCount = 6-strLen;
//这里只考虑了插入和缺少类型的需求。是一个逻辑优化。当最短需求为6个字符时。可以只考虑这两个值。
//如果最短长度较大应该先替换,然后使用插入的方式消除掉替换。
return max(needInsertCharCount,withoutCharTypeCount);
}else if(strLen > 20){//先执行replace,然后更具del的次数进行消除
int needDelCharCount = strLen - 20;//需要删除的字符数
int reduceDel = needDelCharCount;
//尽可能多的抵消替换操作
if(reduceDel > onDelReplaceCount){//优先抵消只需要1个del
reduceDel -= onDelReplaceCount;
needReplaceCharCount -= onDelReplaceCount;
if(reduceDel > twoDelReplaceCount){//再抵消只需要2个del
needReplaceCharCount -= twoDelReplaceCount;
reduceDel -= 2*twoDelReplaceCount;
needReplaceCharCount -= reduceDel/3;//剩余的del 。每3个del可以抵消一个replace
}else{
needReplaceCharCount -= reduceDel/2;
}
}else{
needReplaceCharCount -= reduceDel;
}
return needDelCharCount + max(withoutCharTypeCount,needReplaceCharCount);
}else{//总是只执行replace
return max(needReplaceCharCount,withoutCharTypeCount);
}
}