📅  最后修改于: 2023-12-03 14:50:47.855000             🧑  作者: Mango
有一个长度为 n
,只包含小写字母的字符串 s
,和一个正整数 k
。保证 n
是 k
的倍数。我们把 s
分成长度为 k
的 n/k
个子串。对于每个子串,可以通过交换其中任意两个字符使其变得更小。求交换完所有子串后,最小的字典序是多少。
T
,表示测试用例的数量。T
行,每行包含两个正整数 n
和 k
,以及一个长度为 n
的字符串 s
,描述一个测试用例。对于每个测试用例,输出一行,一个字符串表示交换后最小的字典序是多少。
输入:
2
6 3 abdcba
6 3 abcadc
输出:
`abcdab`
`aabccd`
题目中给出了字符串和子串的长度,可以考虑将每一个子串进行排序,通过排序后的结果直接组合为最终结果即可。排序的效率可以考虑使用计数排序,时间复杂度为 $O(n+k)$。
def min_lexicographical(s: str, k: int) -> str:
n = len(s)
t = n // k
res = ""
for i in range(t):
sub = s[i * k:(i + 1) * k]
cnt = [0] * 26
for c in sub:
cnt[ord(c) - ord('a')] += 1
min_char = 'a'
while cnt[ord(min_char) - ord('a')] == 0:
min_char = chr(ord(min_char) + 1)
for j in range(k):
if sub[j] == min_char:
res += min_char
cnt[ord(min_char) - ord('a')] -= 1
else:
cnt[ord(sub[j]) - ord('a')] -= 1
res += sub[0]
return res
n = int(input())
for _ in range(n):
s_len, k_len, s = input().split()
k = int(k_len)
res = min_lexicographical(s, k)
print(res)
代码中先是将字符串拆分成若干个子串,对于每一个子串使用计数排序确定最终子串的最小字典序。最终将处理结果拼接成最终的字符串输出即可。