返回
LeetCode 探索(111):899-有序队列:打造字典序最小的字符串
前端
2023-12-16 15:02:12
导言
在 LeetCode 的浩瀚题海中,899-有序队列是一个颇具挑战性的题目,它考验着我们的字符串操作功底。这道题要求我们从给定字符串的前 k 个字母中选择一个,并将其添加到字符串末尾,以此构建一个字典序最小的字符串。本文将循序渐进地分析解题思路,并结合代码示例,带你深入理解算法的精髓。
贪心算法的巧妙应用
解决有序队列问题的关键在于应用贪心算法。贪心算法是一种逐步做出最佳选择,以达到全局最优解的算法策略。在这道题中,我们每次从剩余的前 k 个字母中选择字典序最小的字母添加到字符串末尾。
算法步骤
- 将字符串的前 k 个字母排序。
- 依次从排序后的字母中选择字典序最小的字母,添加到字符串末尾。
- 重复步骤 2,直到前 k 个字母都添加完毕。
代码实现
def orderly_queue(s: str, k: int) -> str:
"""
:param s: 给定字符串
:param k: 可移动字母的数量
:return: 字典序最小的字符串
"""
n = len(s)
if k == 0:
return s
s_sorted = sorted(s)
result = ""
for i in range(n):
if s[i] == s_sorted[i]:
continue
index = s_sorted.index(s[i])
if index >= k:
result = s[i:] + s[:i]
else:
result = s_sorted[index] + result
return result
代码解析
- 判断 k 是否为 0,如果是,则无需移动字母,直接返回原始字符串。
- 对字符串的前 k 个字母进行排序,存储在 s_sorted 中。
- 遍历 s,如果 s[i] 等于 s_sorted[i],则表明当前字母已处于正确位置,继续遍历。
- 如果 s[i] 不等于 s_sorted[i],则说明需要移动字母。计算字母在 s_sorted 中的位置 index。
- 如果 index >= k,则表明当前字母需要移动到字符串末尾。否则,需要将当前字母移动到 s_sorted[index] 的前面。
- 更新 result 为移动后的字符串。
实例
输入:
s = "cba"
k = 1
输出:
"acb"
解释:
- 排序前 k 个字母:"abc"
- 选择第一个字母 "a",将其添加到末尾,得到 "cab"。
- 选择第二个字母 "b",将其添加到末尾,得到 "acb"。
"acb" 是字典序最小的字符串。
结语
LeetCode 899-有序队列题目的精妙之处在于其贪心算法的应用。通过贪心地选择字典序最小的字母,我们可以逐步构造出字典序最小的字符串。掌握贪心算法的思想对于解决类似问题至关重要。此外,这道题还考验了我们的字符串操作能力,通过练习,我们可以不断提升自己的编程技能。