携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。
返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 。
示例 1:
输入:s = "cba", k = 1
输出:"acb"
解释:
在第一步中,我们将第一个字符(“c”)移动到最后,获得字符串 “bac”。
在第二步中,我们将第一个字符(“b”)移动到最后,获得最终结果 “acb”。
示例 2:
输入:s = "baaca", k = 3
输出:"aaabc"
解释:
在第一步中,我们将第一个字符(“b”)移动到最后,获得字符串 “aacab”。
在第二步中,我们将第三个字符(“c”)移动到最后,获得最终结果 “aaabc”。
分情况讨论
计算字典序最小的字符串时,需要分别考虑 和 的两种情况。
当 时,每次只能取 的首个字符并将其移动到末尾,因此对于给定的字符串,可能的移动方法是唯一的,移动后的结果也是唯一的。对于长度为 的字符串 ,经过 次到 次移动之后分别得到 个字符串,这 个字符串中的字典序最小的字符串即为答案。
当 时,一定可以经过移动将 变成升序字符串,因此将字符串 升序排序之后得到的字符串即为答案。理由如下。
考虑 的情况。假设 的所有字符按照升序排序依次是 。对于 的任意排列,总是可以经过若干次移动将 变成首个字符。
当 变成首个字符之后,可以将 变成前两个字符:
- 每次将首个字符移动到末尾,直到 变成首个字符;
- 保持 位于首个字符,每次将 后面的字符移动到末尾,直到 后面的字符是
使用同样的方法,对于 ,如果 位于前 个字符,则可以经过若干次移动将 变成前 个字符:
- 每次将首个字符移动到末尾,直到 变成首个字符,此时 为字符串中连续的 个字符;
- 保持 位于首个字符,每次将 后面的字符移动到末尾,直到 后面的字符是 ,此时前 个字符是 。
因此,当 时,一定可以经过移动将 变成升序字符串。
当 时,同样可以对字符串的前两个字符执行移动操作将 变成升序字符串。
var orderlyQueue = function(s, k) {
if (k === 1) {
let ans = s;
for (let i = 0; i < s.length - 1; ++i) {
const n = s.length;
s = s.substring(1, n) + s[0];
ans = ans < s ? ans : s;
}
return ans;
}
return [...s].sort().join('');
};