给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。
请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。
请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。
解法一
写得不好,思路是把数字和字符分别存到list中,然后判断两个list的长度,长的做起始位,长出2个及以上返回"",然后循环拼接到StringBuilder里。
class Solution {
public String reformat(String s) {
//把字符串里的数字和字符分别存放到对应的list中
List<Character> nums = new ArrayList();
List<Character> chars = new ArrayList();
for (char c : s.toCharArray()) {
if (c >= '0' && c <= '9') nums.add(c);
else chars.add(c);
}
//判断两个list的个数
//如果个数相差超过1个,那么就不符合
if (Math.abs(nums.size() - chars.size()) > 1) return "";
//判断是数字多还是字符多,多的当起始位
boolean startNum = nums.size() >= chars.size() ? true : false;
StringBuilder sb = new StringBuilder();
//拼接
int x = 0, y = 0;
while (x < nums.size() && y < chars.size()) {
if (startNum) {
sb.append(nums.get(x));
sb.append(chars.get(y));
} else {
sb.append(chars.get(y));
sb.append(nums.get(x));
}
x++;
y++;
}
//因为循环是用&&,所以可能会有剩余,判断是否还有剩余字符
if (x != nums.size()) sb.append(nums.get(x));
else if (y != chars.size()) sb.append(chars.get(y));
return sb.toString();
}
}
用到了两个list,一个StringBuilder,空间用多了,直接步骤也过多,效率不行,解法二我直接复制过来,写得挺厉害的,我在这里卡了半天,中间因为逻辑出错,又重新推到重来。
解法二
解法二是在题解区复制过来的。(作者:1905215165)
解法二的思路:先把所有字符存到数组里,然后遍历得出,数字和字符的数量;然后判断是哪个数量多,多的做起始位,如果其中数量比另一个多出2个及以上,就返回"";这里和我步骤差不多,接下来就厉害了,使用增强for循环遍历判断是数字还是字符,然后放到原数组里,每次加2,这样数字和字符就不会冲突,各自做各自的,这点省去了很多判断。
class Solution {
public String reformat(String s) {
int num1=0,num2=0;
char[] chars = s.toCharArray();
for(char c:chars){
if(c >= '0'&&c <= '9'){num1++;}
else{num2++;}
}//看数字字符比较多还是字母字符比较多
if( num1-num2<-1 || num1-num2>1){return "";}
if(num1>num2){
num1 = 0;num2 = 1;
}else{
num1 = 1;num2 = 0;
}
for(char c:s.toCharArray()){
if(c >= '0'&&c <= '9'){chars[num1] = c; num1 += 2;}
else{chars[num2] = c; num2 += 2;}
}
return new String(chars);
}
}
//作者:1905215165