给你一个字符串 s
,请你根据下面的算法重新构造字符串:
- 从
s
中选出 最小 的字符,将它 接在 结果字符串的后面。 - 从
s
剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。 - 重复步骤 2 ,直到你没法从
s
中选择字符。 - 从
s
中选出 最大 的字符,将它 接在 结果字符串的后面。 - 从
s
剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。 - 重复步骤 5 ,直到你没法从
s
中选择字符。 - 重复步骤 1 到 6 ,直到
s
中所有字符都已经被选过。
在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。
请你返回将 s
中字符重新排序后的 结果字符串 。
示例 1:
输入:s = "aaaabbbbcccc" 输出:"abccbaabccba" 解释:第一轮的步骤 1,2,3 后,结果字符串为 result = "abc" 第一轮的步骤 4,5,6 后,结果字符串为 result = "abccba" 第一轮结束,现在 s = "aabbcc" ,我们再次回到步骤 1 第二轮的步骤 1,2,3 后,结果字符串为 result = "abccbaabc" 第二轮的步骤 4,5,6 后,结果字符串为 result = "abccbaabccba"
示例 2:
输入:s = "rat" 输出:"art" 解释:单词 "rat" 在上述算法重排序以后变成 "art"
示例 3:
输入:s = "leetcode" 输出:"cdelotee"
示例 4:
输入:s = "ggggggg" 输出:"ggggggg"
示例 5:
输入:s = "spo" 输出:"ops"
提示:
1 <= s.length <= 500
s
只包含小写英文字母。
思路:这类题目采用技术法最好做了,上次有个类似题目通过一个flag数组来统计s中各个字母有没有被用过,在这题也试了一下,差点没把自己累死。尝试着采用桶计数法来解决问题:定义一个Map对象来统计一下s中各个字母各有多少个,然后后续处理每用一次就在相应的桶里面减一。
![](https://i-blog.csdnimg.cn/blog_migrate/50fb183c5ff990f7e2c007843caa5cfc.png)
流程:每一次遍历字符串时先升序排序,然后结果中存一遍字符,再降序一遍存一遍字符,直到结果的长度和s的长度一致,说明字母全部被用完了。java代码实现如下:
class Solution {
public String sortString(String s) {
if (s.length()==0 || s==null) {
return ""; }
String res = "";
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (char ch : s.toCharArray()) {
if (!map.containsKey(ch)) {
map.put(ch, 0);
}else {
map.put(ch, map.get(ch)+1); //统计各个字符出现的次数
}
}
Set<Character> chs = map.keySet();
while (true) {
Set<Character> sortSet = new TreeSet<Character>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o1.compareTo(o2); //升序排序
};
});
sortSet.addAll(chs);
Iterator<Character> iterator = sortSet.iterator();
while (iterator.hasNext()) {
char c = iterator.next();
if (map.get(c) != -1) {
res+=c; //使用字母返回结果
map.put(c, map.get(c)-1);
}
}
sortSet = new TreeSet<Character>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o2.compareTo(o1); //降序排序
};
});
sortSet.addAll(chs);
Iterator<Character> iterator2 = sortSet.iterator();
while (iterator2.hasNext()) {
char c = iterator2.next();
if (map.get(c) != -1) {
res+=c; //使用字母返回结果
map.put(c, map.get(c)-1);
}
}
if (res.length() == s.length()) { //字母使用完
break;
}
}
return res;
}
}