(LeetCode 1370 简单)
给你一个字符串 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 只包含小写英文字母。
题解分析:
本题可以使用桶排序求解(升序),按照桶的顺序正向输出一次,然后再逆序输出一次,直到桶中所有存放的数据都输出完毕。需要注意的是。
本题的字符构成全部是英文小写字母,因此需要申请26个桶,其中第0号桶对应'a',第1号桶对应‘b’,第2号桶对应‘c’,以此类推;
每一个桶记录的是字符串中每一个字母出现的次数,比如a出现了3次,那么数组中第0号索引对应的数值就为3;
统计字符串中每一个字符出现的次数时,需要使用ASCII码,比如使用了char类型的数据保存了一个字母b,那么将其存储到第1号桶中,需要b减去a(计算这些字符时,使用了ASCII码,b的ASCII为98,而a的为97,两者相减为1)。
排序结束后,需要按照向前遍历依次桶元素和向后遍历一次桶元素的方式遍历完毕桶的元素。此时可以使用一个字符串将元素进行拼接:前者桶的索引区间为[0,25],后者为[25,0]。
代码如下:
class Solution {
public String sortString(String s) {
int[] buckets = new int[26];
int index = 0;
String result = "";
for(; index < s.length(); index ++){
buckets[s.charAt(index) - 'a'] ++;
}
while(result.length() != s.length()){
for(index = 0; index < buckets.length; index ++){
if(buckets[index] != 0){
result += String.valueOf((char) (index + 'a'));
buckets[index] --;
}
}
for(index = buckets.length - 1; index >= 0; index --){
if(buckets[index] != 0){
result += String.valueOf((char)(index + 'a'));
buckets[index] --;
}
}
}
return result;
}
}