theme: juejin
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
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 只包含小写英文字母。
原题传送门:
https://leetcode.cn/problems/increasing-decreasing-string/
分析
- 面对这道算法题目,二当家的陷入了沉思。
- 题目带有一定的迷惑性,想要引导人们模拟。
- 但是仔细理解题意发现,其实是将字符串中的字符排序,按照从小到大排列字母(字母不可以重复),再从大到小排列字母(字母不可以重复),不断往复,直到所有字母排列完,查看几个样例数据也证实了我的想法。
- 题意并不是要求所有字母从小到大排列,而是每次挑不同的字母。假设我们把字母分组,并且从'a'到'z',从左到右放好,我们就只需要从左拿到右,再从右拿到左,直到全部拿完。
- 按字母计数来达到按字母分组的效果,以字母顺序为下标,达到分组排序的效果。
题解
rust
impl Solution {
pub fn sort_string(s: String) -> String {
// 计数同时完成排序
let mut cnt = [0; 26];
s.as_bytes().iter().for_each(|&b| {
cnt[(b - b'a') as usize] += 1;
});
let mut ans = String::new();
while ans.len() < s.len() {
(0..26).chain((0..26).rev()).for_each(|i| {
if cnt[i] > 0 {
ans.push((b'a' + i as u8) as char);
cnt[i] -= 1;
}
});
}
return ans;
}
}
go
func sortString(s string) string {
// 计数同时完成排序
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
}
bs := make([]byte, 0, len(s))
for len(bs) < len(s) {
// 正
for i := 0; i < 26; i++ {
if cnt[i] > 0 {
bs = append(bs, byte('a'+i))
cnt[i]--
}
}
// 逆
for i := 25; i >= 0; i-- {
if cnt[i] > 0 {
bs = append(bs, byte('a'+i))
cnt[i]--
}
}
}
return string(bs)
}
c++
class Solution {
public:
string sortString(string s) {
// 计数同时完成排序
int cnt[26] = {};
for (auto c: s) {
++cnt[c - 'a'];
}
string ans;
while (ans.length() < s.length()) {
// 正
for (int i = 0; i < 26; ++i) {
if (cnt[i] > 0) {
ans.push_back('a' + i);
--cnt[i];
}
}
// 逆
for (int i = 25; i >= 0; --i) {
if (cnt[i] > 0) {
ans.push_back('a' + i);
--cnt[i];
}
}
}
return ans;
}
};
java
class Solution {
public String sortString(String s) {
// 计数同时完成排序
int[] cnt = new int[26];
for (char c : s.toCharArray()) {
++cnt[c - 'a'];
}
StringBuilder sb = new StringBuilder();
while (sb.length() < s.length()) {
// 正
for (int i = 0; i < 26; ++i) {
if (cnt[i] > 0) {
sb.append((char) ('a' + i));
--cnt[i];
}
}
// 逆
for (int i = 25; i >= 0; --i) {
if (cnt[i] > 0) {
sb.append((char) ('a' + i));
--cnt[i];
}
}
}
return sb.toString();
}
}
python
class Solution:
def sortString(self, s: str) -> str:
# 计数同时完成排序
cnt = [0] * 26
for c in s:
cnt[ord(c) - 97] += 1
ans = []
while len(ans) < len(s):
#正
for i in range(26):
if cnt[i] > 0:
ans.append(chr(97 + i))
cnt[i] -= 1
#逆
for i in range(25, -1, -1):
if cnt[i] > 0:
ans.append(chr(97 + i))
cnt[i] -= 1
return "".join(ans)
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情