想了解更多数据结构以及算法题,可以关注微信公众号“数据结构和算法”,每天一题为你精彩解答。也可以扫描下面的二维码关注
问题描述
给你一个字符串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 只包含小写英文字母。
问题分析
这道题是让从字符串s中先选出升序的字符,然后再选出降序字符……一直这样循环,直到选完为止。因为题中的提示中说了s只包含小写英文字符,我们可以申请一个大小为26的数组,相当于26个桶。
-
把s中的每个字符分别放到对应的桶里,比如a放到第一个桶里,b放到第2个桶里……。
-
第1次从左往右遍历26个桶,从每个桶里拿出一个字符(如果没有就不用拿)
-
第2次从右往左遍历26个桶,从每个桶里拿出一个字符(如果没有就不用拿)
-
……
-
一直这样循环下去,直到所有的桶里的元素都拿完为止。
这里以示例为例,来画个图看下
原理比较简单,来看下代码
public String sortString(String s) {
//相当于26个桶
int[] bucket = new int[26];
char[] charArr = s.toCharArray();
//把s中的字符分别放到对应的桶里
for (char c : charArr) {
bucket[c - 'a']++;
}
//存储计算的结果
char[] res = new char[s.length()];
int index = 0;
while (index < s.length()) {
//先从左往右找,遍历26个桶,如果当前桶不为空,
//就从当前桶里拿出一个元素出来
for (int i = 0; i < 26; i++) {
if (bucket[i] != 0) {
res[index++] = (char) (i + 'a');
bucket[i]--;//拿出之后桶中元素的个数要减1
}
}
//从右往左拿,同上
for (int i = 25; i >= 0; i--) {
if (bucket[i] != 0) {
res[index++] = (char) (i + 'a');
bucket[i]--;
}
}
}
//把结果转化为字符串
return new String(res);
}
总结
这题算是比较简单,只需要把每个字符都放到对应的桶里,然后每次从左往右把26个桶过一遍,接着在从右往左把26个桶过一遍,直到所有桶里的元素都空为止。