问题描述
给定一个字符串 ss,该字符串中只包含英文大小写字母。你需要计算从字符串中最多能组成多少个字符串 "ku"。每次可以随机从字符串中选一个字符,并且选中的字符不能再使用。字符串中的字符大小写可以忽略,即大写和小写字母视为相同。
例如,输入 "AUBTMKAxfuu",从中最多能组成 1 个 "ku"。
测试样例
样例1:
输入:
s = "AUBTMKAxfuu"
输出:1
样例2:
输入:
s = "KKuuUuUuKKKKkkkkKK"
输出:6
样例3:
输入:
s = "abcdefgh"
输出:0
问题分析
数据结构选择
- 字符计数:由于我们需要统计字符
'k'和'u'的出现次数,可以使用一个字典来记录每个字符的出现次数。
算法步骤
- 转换为小写:首先将字符串转换为小写,以便忽略大小写。
- 统计字符出现次数:遍历字符串,统计每个字符的出现次数。
- 计算
"ku"的数量:字符'k'和'u'的出现次数的最小值即为最多能组成的"ku"的数量。
关键点
- 字符串转换为小写后,统计
'k'和'u'的出现次数。 - 使用字典来记录字符的出现次数。
- 最终结果是
'k'和'u'出现次数的最小值。
代码
def solution(s: str) -> int:
# 将字符串转换为小写
s = s.lower()
# 统计字符出现次数
char_count = {}
for char in s:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
# 计算 "ku" 的数量
k_count = char_count.get('k', 0)
u_count = char_count.get('u', 0)
# 返回 "ku" 的数量
return min(k_count, u_count)
if __name__ == '__main__':
print(solution("AUBTMKAxfuu") == 1)
print(solution("KKuuUuUuKKKKkkkkKK") == 6)
print(solution("abcdefgh") == 0)
复杂度分析
时间复杂度分析
-
转换为小写: 这一步的时间复杂度是 O(n),其中 n 是字符串的长度。因为
lower()方法需要遍历整个字符串来将其转换为小写。 -
统计字符出现次数:
这一步的时间复杂度也是 O(n)。我们遍历字符串
s一次,对于每个字符,我们执行常数时间的操作(检查字典中是否存在该字符,并更新计数)。 -
计算 "ku" 的数量:
这一步的时间复杂度是 O(1),因为
get方法在字典中查找键的时间复杂度是常数时间。 -
返回 "ku" 的数量:
综上所述,整个函数的时间复杂度是 O(n),其中 n 是字符串的长度。
空间复杂度分析
-
字符计数字典:
这个字典的空间复杂度是 O(k),其中 k 是字符串中不同字符的数量。在最坏情况下,字符串中每个字符都不同,因此 k 的最大值是 26(因为只包含英文字母)。
-
其他变量:
这些变量的空间复杂度是 O(1),因为它们只占用常数空间。
综上所述,整个函数的空间复杂度是 O(k),其中 k 是字符串中不同字符的数量,最大值为 26。
代码优化
优化思路
-
减少不必要的字符串操作:
- 当前代码中,
s.lower()将整个字符串转换为小写。虽然这个操作的时间复杂度是 O(n),但在某些情况下,我们可以通过直接处理字符来避免这个操作。
- 当前代码中,
-
优化字符计数:
- 当前代码使用字典来统计字符出现次数。虽然字典的查找和插入操作是 O(1) 的,但我们可以考虑使用更高效的数据结构或方法来进一步优化。
-
减少内存使用:
- 当前代码使用字典来存储字符计数,这会占用一定的内存。我们可以考虑使用更节省内存的数据结构或方法。
优化方向
-
直接处理字符:
- 我们可以直接在遍历字符串时处理字符,而不需要先将字符串转换为小写。这样可以避免不必要的字符串操作。
-
使用数组进行字符计数:
- 由于字符串只包含英文字母,我们可以使用一个长度为 26 的数组来统计每个字母的出现次数。这样可以减少字典的开销,并且数组的访问速度更快。
-
减少内存使用:
- 如果我们只关心字符
'k'和'u'的出现次数,可以在遍历字符串时直接累加这两个字符的计数,而不需要存储其他字符的计数。
- 如果我们只关心字符