1.题目
You are given a license key represented as a string S which consists only alphanumeric character and dashes. The string is separated into N+1 groups by N dashes.
Given a number K, we would want to reformat the strings such that each group contains exactly K characters, except for the first group which could be shorter than K, but still must contain at least one character. Furthermore, there must be a dash inserted between two groups and all lowercase letters should be converted to uppercase.
Given a non-empty string S and a number K, format the string according to the rules described above.
翻译:
给定一个字符串S表示的许可秘钥,S仅由字母数字和分隔符组成。字符串被N个分隔符分隔成N+1组。
给定一个数字K,我们希望重新排列字符串,使其除了第一组外每组包含K个字符,第一组可以比K个字符少,但是至少也要包含一个字符。此外,每两组之间必须有一个分隔符,并且所有的小写字母要转换成大写字母。
给定一个非空字符串S和一个数字K,根据上面描述的规则,重新格式化字符串。
Example 1:
Input: S = "5F3Z-2e-9-w", K = 4 Output: "5F3Z-2E9W" Explanation: The string S has been split into two parts, each part has 4 characters. Note that the two extra dashes are not needed and can be removed.
Example 2:
Input: S = "2-5g-3-J", K = 2 Output: "2-5G-3J" Explanation: The string S has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
Note:
- The length of string S will not exceed 12,000, and K is a positive integer.
- String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).
- String S is non-empty.
提示:
1.字符串S的长度不会超过12000,K是一个正整数。
2.字符串S仅由字母数字(a-z|A-Z|0-9)和分隔符(-)组成。
3.字符串S非空。
2.思路
错误思路:开始的时候我是正序处理的,如果是第一组(即从未遇到分隔符),字符数<=K即可,后面的每四个拆拼成一组。这种思路前面处理都是对的,但是会导致最后一组的字符数可能会小于K个。
正确思路:逆序开始处理,用一个变量temp计数(为了四个一组),当字符串未处理完,且temp为 4 时拼接一个“-”。当前字符为“-”时直接跳过;遇到“0-9”或“A-Z”时拼接当前字符,temp+1;遇到“a-z”时,将其变化成大写字母再拼接,temp+1。最后完全处理后,再进行一次逆操作。
特殊地,有一种特殊情况,如第一次逆操作后,字符串形如“23Az-123F-----”(字符串由1个以上的“-”结束,会返回“-F321-ZA32”。)因此要判断,两次逆操作之后的字符串是否是分隔符开头的,是的话进行一次字符串截取操作。两次逆操作之后字符串最多是一个“-”开头,不会出现多个“-”开头。
3.算法
public String licenseKeyFormatting(String S, int K) {
int len=S.length();
int temp=0;
StringBuilder sb=new StringBuilder();
for(int i=len-1;i>=0;i--){
char c=S.charAt(i);
if(temp==K){
sb.append("-");
temp=0;
}
if(c>='a'&&c<='z'){
sb.append((""+c).toUpperCase());
temp++;
}else if((c>='A'&&c<='Z')||(c>='0'&&c<='9')){
sb.append(c);
temp++;
}
}
String res=sb.reverse().toString();
if(res.length()!=0&&res.charAt(0)=='-')
res=res.substring(1);
return res;
}
4.总结
其实很简单的算法题,也折腾了一会。如果是开头特殊的话,可以考虑从尾巴开始处理,把特殊的留下处理。