LeetCode探索(111):899-有序队列

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情 >>

题目

给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。

返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串

示例 1:

输入:s = "cba", k = 1
输出:"acb"
解释:
在第一步中,我们将第一个字符(“c”)移动到最后,获得字符串 “bac”。
在第二步中,我们将第一个字符(“b”)移动到最后,获得最终结果 “acb”。
复制代码

示例 2:

输入:s = "baaca", k = 3
输出:"aaabc"
解释:
在第一步中,我们将第一个字符(“b”)移动到最后,获得字符串 “aacab”。
在第二步中,我们将第三个字符(“c”)移动到最后,获得最终结果 “aaabc”。
复制代码

提示:

  • 1 <= k <= S.length <= 1000
  • s 只由小写字母组成。

思考

本题难度困难。

首先是读懂题意。给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。我们最终返回的是在应用上述步骤的任意数量的移动后,字典上最小的字符串。

我们分类讨论一下。当 k = 1 时,我们每次只能移动字符串的第一个字符,得到一个新的字符串。经过 n - 1 次操作后,最终的结果为这n个字符串中字典序最小的那个字符串。当 k > 1 时,我们可以经过多次操作,最终得到任意顺序的字符串。因此,我们返回字符串经过字典序排序后的结果即可。

解答

方法一:分类讨论

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var orderlyQueue = function(s, k) {
  if (k === 1) {
    let ans = s, len = s.length
    for (let i = 0; i < len - 1; ++i) {
      s = s.substring(1, len) + s[0]
      ans = ans < s ? ans : s
    }
    return ans
  }
  return [...s].sort().join('')
}
复制代码

复杂度分析:

  • 时间复杂度:O(n) 或 O(nlogn),其中 n 是字符串 s 的长度。当 k = 1 时需要遍历 n 个可能的字符串,时间复杂度是 O(n);当 k > 1 时需要对字符串排序,时间复杂度是 O(nlogn)。
  • 空间复杂度:O(1) 或 O(logn),其中 n 是字符串 s 的长度。只有当 k > 1 时排序需要 O(logn) 的空间。

参考

猜你喜欢

转载自juejin.im/post/7127671058278121486