问题描述
小C 需要对一个字符串进行特殊排序,这个字符串只包含三种字符类型:字母(大小写)、数字和问号。要求你按照以下规则进行排序:
- 问号的原始位置必须保持不变。
- 数字的原始位置必须保持不变,但数字要按照从大到小排序。
- 字母的原始位置必须保持不变,但字母要按照字典序从小到大排序。
你需要编写一个程序,帮助小C实现这个字符串的排序功能。
测试样例
样例1:
输入:
inp = "12A?zc"
输出:'21A?cz'
样例2:
输入:
inp = "1Ad?z?t24"
输出:'4Ad?t?z21'
样例3:
输入:
inp = "???123??zxy?"
输出:'???321??xyz?'
要实现这个排序规则,我们可以分别提取字母和数字,然后对其排序,最后按照原始字符串的问号、数字和字母位置插入排序后的结果。
解题思路:
-
遍历字符串:
- 把 字母 收集到一个列表
letters。 - 把 数字 收集到一个列表
numbers。 - 保留问号的位置(直接跳过问号)。
- 把 字母 收集到一个列表
-
对字母和数字排序:
letters按字典序升序排序。numbers按从大到小排序。
-
重新插入字符:
- 按照字符串的原始位置重新组装字符串。
- 如果当前字符是问号,直接插入。
- 如果是数字或字母,从排序好的列表中取出。
样例分析
"1Ad?z?t24"
输入解析:
字符串包含:
- 数字:
1, 2, 4 - 字母:
A, d, z, t - 问号:
?, ?
步骤:
-
提取数字和字母:
- 数字列表:
[1, 2, 4] - 字母列表:
['A', 'd', 'z', 't']
- 数字列表:
-
排序:
- 数字按降序:
[4, 2, 1] - 字母按字典序:
['A', 'd', 't', 'z']
- 数字按降序:
-
重建字符串:
-
遍历原字符串:
- 遇到
1:插入排序后的数字4。 - 遇到
A:插入排序后的字母A。 - 遇到
d:插入排序后的字母d。 - 遇到
?:保留问号。 - 遇到
z:插入排序后的字母t。 - 遇到
?:保留问号。 - 遇到
t:插入排序后的字母z。 - 遇到
2:插入排序后的数字2。 - 遇到
4:插入排序后的数字1。
- 遇到
-
输出:"4Ad?t?z21"
代码实现(java版)
import java.util.ArrayList;
import java.util.List;
public class Main {
public static String solution(String inp) {
// Edit your code here
List<Character> letters = new ArrayList<>();
List<Character> numbers = new ArrayList<>();
for (char ch : inp.toCharArray()) {
if (Character.isLetter(ch)) {
letters.add(ch);
} else if (Character.isDigit(ch)) {
numbers.add(ch);
}
}
letters.sort(Character::compareTo);
numbers.sort((a, b) -> b - a);
StringBuilder result = new StringBuilder();
int letterIndex = 0, numberIndex = 0;
for (char ch : inp.toCharArray()) {
if (ch == '?') {
result.append('?');
} else if (Character.isLetter(ch)) {
result.append(letters.get(letterIndex++));
} else if (Character.isDigit(ch)) {
result.append(numbers.get(numberIndex++));
}
}
return result.toString();
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution("12A?zc").equals("21A?cz"));
System.out.println(solution("1Ad?z?t24").equals("4Ad?t?z21"));
System.out.println(solution("???123??zxy?").equals("???321??xyz?"));
}
}
复杂度分析:
-
时间复杂度:
- 遍历字符串:O(n)O(n)O(n)。
- 排序字母和数字:O(klogk)O(k \log k)O(klogk) 和 O(mlogm)O(m \log m)O(mlogm)(其中 kkk 是字母的数量,mmm 是数字的数量)。
- 总计:O(n+klogk+mlogm)O(n + k \log k + m \log m)O(n+klogk+mlogm)。
-
空间复杂度:
- 存储字母和数字列表:O(k+m)O(k + m)O(k+m)。