# May be the longest code but easy understand Java solution.

• I use code to deal with all details.

``````public class Solution {
int len = s.length(),count = 1;
boolean hasLower = false,hasUpper = false,hasNumber = false;
List<Integer> repeatNum = new ArrayList<Integer>();
for(int i=0;i<len;i++){
if(i>0){
if(s.charAt(i) == s.charAt(i-1)){
count += 1;
}
else{
count = 1;
}
}
char ch = s.charAt(i);
if('a'<= ch && ch<='z') hasLower = true;
if('A'<= ch && ch<='Z') hasUpper = true;
if('0'<= ch && ch<='9') hasNumber = true;
}
int needAdd = 0,res = 0;
Collections.sort(repeatNum,new Comparator(){
@Override
public int compare(Object o1,Object o2){
int val1 = (Integer)(o1),val2 = (Integer)(o2);
return (val1%3)-(val2%3);
}
});
if(6<=len && len<=20){
int needChange = 0;
for(int i=0;i<repeatNum.size();i++){
needChange += repeatNum.get(i)/3;
}
}else{
if(len>20)
{
int needChange = 0,needDel = len-20,index = 0;
while(needDel>0 && repeatNum.size()>0){
int val = repeatNum.get(index);
if(val/3 == (val-1)/3+1){
needDel -= 1;
if((val-1)/3==0) repeatNum.remove(index);
else repeatNum.set(index,val-1);
}
index += 1;
if(index >= repeatNum.size()) break;
}
index = 0;
while(needDel>1 && repeatNum.size()>0){
int val = repeatNum.get(index);
if(val/3 == (val-2)/3+1){
needDel -= 2;
if((val-2)/3 == 0) repeatNum.remove(index);
else repeatNum.set(index,val-2);
}
index += 1;
if(index >= repeatNum.size()) break;
}
index = 0;
while(needDel>2 && repeatNum.size()>0){
int val = repeatNum.get(index);
if(val/3 == (val-3)/3+1){
needDel -= 3;
if((val-3)/3 == 0) repeatNum.remove(index);
else repeatNum.set(index,val-3);
}
index += 1;
if(index >= repeatNum.size()) index = 0;
}
for(int i=repeatNum.size()-1;i>-1 && needDel>0;i--){
if(repeatNum.get(i)-2<=needDel){
needDel -= repeatNum.get(i)-2;
repeatNum.remove(i);
}else{
repeatNum.set(i,repeatNum.get(i)-1);
needDel = 1;
}
}

for(int i=0;i<repeatNum.size();i++){
needChange += repeatNum.get(i)/3;
}