最小替换子串长度
问题描述
小R对字符串的子串非常感兴趣,特别是关于所有不同的子串。他有一个字符串s,想知道其中第k小的不同子串是什么。小R希望你能帮他找到答案。如果第k小的子串不存在,则返回NO ANSWER。
例如,给定字符串s = "aab",我们可以列出所有不同的子串,并按字典序排序。小R想知道排在第k小的子串是什么。
测试样例
样例1:
输入:
s = "aab",k = 4
输出:'ab'
样例2:
输入:
s = "abc",k = 6
输出:'c'
样例3:
输入:
s = "banana",k = 10
输出:'banan'
思路解析
- 生成所有子串:我们需要遍历字符串
s,生成所有可能的子串。 - 去重:由于子串可能重复,我们需要使用集合(
set)来存储子串,以确保所有子串都是唯一的。 - 排序:将集合中的子串按字典序排序。
- 查找第
k小的子串:从排序后的子串列表中找到第k小的子串。
解题代码
def solution(s: str, k: int) -> str:
# 1. 生成所有子串并存储在集合中
substrings = set()
for i in range(len(s)):
for j in range(i + 1, len(s) + 1):
substrings.add(s[i:j])
# 2. 将子串按字典序排序
sorted_substrings = sorted(substrings)
# 3. 查找第 k 小的子串
if k <= len(sorted_substrings):
return sorted_substrings[k - 1]
else:
return "NO ANSWER"
代码模块详解
-
生成所有子串:
- 使用两个嵌套的循环来生成所有可能的子串。外层循环控制子串的起始位置,内层循环控制子串的结束位置。
- 将生成的子串添加到集合
substrings中,以确保所有子串都是唯一的。
-
排序:
- 使用
sorted()函数对集合中的子串按字典序排序。
- 使用
-
查找第
k小的子串:- 检查
k是否在排序后的子串列表的长度范围内。如果是,返回第k小的子串;否则返回"NO ANSWER"。
- 检查
复杂度分析
时间复杂度分析
-
生成所有子串:
- 外层循环
for i in range(len(s))运行n次(n是字符串s的长度)。 - 内层循环
for j in range(i + 1, len(s) + 1)运行n - i次。 - 因此,生成所有子串的时间复杂度为
O(n^2),因为总共有n + (n-1) + (n-2) + ... + 1个子串,这是一个等差数列求和,结果是O(n^2)。
- 外层循环
-
去重:
- 使用集合
set来存储子串,插入操作的时间复杂度是O(1)。 - 因此,去重的时间复杂度也是
O(n^2)。
- 使用集合
-
排序:
- 假设生成的不同子串数量为
m(m最大为n(n+1)/2),排序的时间复杂度为O(m log m)。 - 在最坏情况下,
m接近n^2,所以排序的时间复杂度为O(n^2 log n)。
- 假设生成的不同子串数量为
-
查找第
k小的子串:- 查找操作的时间复杂度是
O(1)。
- 查找操作的时间复杂度是
综上所述,总的时间复杂度为 O(n^2) + O(n^2) + O(n^2 log n) = O(n^2 log n)。
空间复杂度分析
-
存储所有子串:
- 使用集合
set存储所有不同的子串,最坏情况下需要存储n(n+1)/2个子串,因此空间复杂度为O(n^2)。
- 使用集合
-
排序后的子串列表:
- 排序后的子串列表也需要存储
m个子串,最坏情况下m接近n^2,因此空间复杂度为O(n^2)。
- 排序后的子串列表也需要存储
综上所述,总的空间复杂度为 O(n^2)。
总结
- 时间复杂度:
O(n^2 log n) - 空间复杂度:
O(n^2)