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.
摘自
https://discuss.leetcode.com/topic/64511/java-with-detailed-explanation
public class Solution {
public int strongPasswordChecker(String s)
{
int len=s.length();
int neededNum=getNeededNum(s);
if(len<6)
return Math.max(6-len, neededNum);
ArrayList<Integer> groups=new ArrayList<>();
GeneralGroups(groups, s);
if(s.length()<=20)
{
int replace=0;
for(int num :groups)
replace+=num/3;
return Math.max(replace, neededNum);
}
Collections.sort(groups);
int charCount=0;
int n=0;
while(charCount<20&&n<groups.size())
{
charCount+=groups.get(n);
n++;
}
while(groups.size()>n)
groups.remove(groups.size()-1);
charCount=0;
int badGroups=0;
for(int i=0;i<groups.size();i++)
{
if(groups.get(i)>20)
groups.set(i, 20);
charCount+=groups.get(i);
if(groups.get(i)>2)
badGroups++;
}
int deletion=len-20;
int toDelete=charCount-20;
int remainder=0;
while(toDelete>0&&badGroups>0)
{
for(int i=0;i<n;i++)
{
int count=groups.get(i);
if(count>2&&count%3==remainder)
{
int del=Math.min(toDelete, remainder+1);
groups.set(i, count-del);
toDelete-=del;
if(groups.get(i)<=2)
badGroups--;
if(toDelete==0||badGroups==0)
break;
}
}
remainder=(remainder+1)%3;
}
int replace=0;
for(int group : groups)
replace+=group/3;
return deletion+Math.max(replace, neededNum);
}
public int getNeededNum(String s)
{
boolean lower=false,upper=false,digit=false;
for(int i=0;i<s.length();i++)
{
char c=s.charAt(i);
lower=lower||(c>='a'&&c<='z');
upper=upper||(c>='A'&&c<='Z');
digit=digit||(c>='0'&&c<='9');
}
return (lower?0:1)+(upper?0:1)+(digit?0:1);
}
public void GeneralGroups(ArrayList<Integer> groups,String s)
{
for(int i=0;i<s.length();)
{
char c=s.charAt(i);
int j=i+1;
while(j<s.length())
if(s.charAt(j)==c)
j++;
else {
break;
}
groups.add(j-i);
i=j;
}
}
}