不同整数的计数问题
问题描述
小R有一个字符串 word,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。
例如,给定字符串 "a123bc34d8ef34",替换后形成的字符串是 " 123 34 8 34",剩下的整数是 "123"、"34"、"8" 和 "34"。不同的整数有三个,即 "123"、"34" 和 "8"。
注意,只有当两个整数的不含前导零的十进制表示不同,才认为它们是不同的整数。
测试样例
样例1:
输入:
word = "a123bc34d8ef34"输出:3
样例2:
输入:
word = "t1234c23456"输出:2
样例3:
输入:
word = "a1b01c001d4"输出:2
好的,根据编辑区的代码,我将给出完整的题解,包括解题思路、代码实现和测试用例。
解题思路
- 字符串处理:遍历字符串
word,将所有非数字字符替换为空格。 - 提取整数:将处理后的字符串按空格分割,提取出所有整数。
- 去除前导零:去除每个整数的前导零。
- 去重:使用集合(set)来存储不同的整数,这样可以自动去重。
- 统计不同整数的数量:返回集合的大小。
Python3代码(通过豆包Marscode测试)
def solution(word: str) -> int:
# 1. 将所有非数字字符替换为空格
word = ''.join(c if c.isdigit() else ' ' for c in word)
# 2. 按空格分割字符串,提取出所有整数
numbers = word.split()
# 3. 去除每个整数的前导零
numbers = [num.lstrip('0') for num in numbers]
# 4. 使用集合存储不同的整数
unique_numbers = set(numbers)
# 5. 返回集合的大小,即不同整数的数量
return len(unique_numbers)
if __name__ == '__main__':
print(solution("a123bc34d8ef34") == 3)
print(solution("t1234c23456") == 2)
print(solution("a1b01c001d4") == 2)
关键步骤解释
-
替换非数字字符:
word = ''.join(c if c.isdigit() else ' ' for c in word)这行代码使用列表推导式遍历字符串
word,将每个非数字字符替换为空格。 -
提取整数:
numbers = word.split()这行代码使用
split()方法按空格分割字符串,提取出所有整数。 -
去除前导零:
numbers = [num.lstrip('0') for num in numbers]这行代码使用列表推导式遍历
numbers列表,对每个整数调用lstrip('0')方法去除前导零。 -
去重:
unique_numbers = set(numbers)这行代码使用集合
set来存储不同的整数,自动去重。 -
统计不同整数的数量:
return len(unique_numbers)这行代码返回集合的大小,即不同整数的数量。
好的,我们来分析一下代码的时间复杂度和空间复杂度。
时间复杂度
-
替换非数字字符:
word = ''.join(c if c.isdigit() else ' ' for c in word)这行代码使用列表推导式遍历字符串
word,时间复杂度为O(n),其中n是字符串的长度。 -
提取整数:
numbers = word.split()这行代码使用
split()方法按空格分割字符串,时间复杂度为O(n),其中n是字符串的长度。 -
去除前导零:
numbers = [num.lstrip('0') for num in numbers]这行代码使用列表推导式遍历
numbers列表,对每个整数调用lstrip('0')方法去除前导零。假设numbers列表中有m个整数,每个整数的长度为k,则时间复杂度为O(m * k)。 -
去重:
unique_numbers = set(numbers)这行代码使用集合
set来存储不同的整数,时间复杂度为O(m),其中m是numbers列表的长度。 -
统计不同整数的数量:
return len(unique_numbers)这行代码返回集合的大小,时间复杂度为
O(1)。
综合来看,代码的总时间复杂度为 O(n + m * k),其中 n 是字符串的长度,m 是提取出的整数数量,k 是每个整数的平均长度。
空间复杂度
-
替换非数字字符:
word = ''.join(c if c.isdigit() else ' ' for c in word)这行代码生成了一个新的字符串,空间复杂度为
O(n),其中n是字符串的长度。 -
提取整数:
numbers = word.split()这行代码生成了一个列表
numbers,空间复杂度为O(m),其中m是提取出的整数数量。 -
去除前导零:
numbers = [num.lstrip('0') for num in numbers]这行代码生成了一个新的列表
numbers,空间复杂度为O(m),其中m是提取出的整数数量。 -
去重:
unique_numbers = set(numbers)这行代码生成了一个集合
unique_numbers,空间复杂度为O(m),其中m是numbers列表的长度。
综合来看,代码的总空间复杂度为 O(n + m),其中 n 是字符串的长度,m 是提取出的整数数量。
算法复杂度
- 时间复杂度:
O(n + m * k) - 空间复杂度:
O(n + m)
其中 n 是字符串的长度,m 是提取出的整数数量,k 是每个整数的平均长度。
前导零
前导零(Leading Zeros)是指在数字字符串或整数表示中,位于最前面的零。例如,在字符串 "00123" 中,前导零是 "00",在字符串 "000456" 中,前导零是 "000"。
例子
"00123"中的前导零是"00",去除前导零后得到"123"。"000456"中的前导零是"000",去除前导零后得到"456"。"00000"中的前导零是"00000",去除前导零后得到""(空字符串)。
为什么要去除前导零?
在某些情况下,前导零可能会影响数字的比较和处理。例如,字符串 "001" 和 "1" 在字符串比较时是不同的,但在数字比较时是相同的。因此,去除前导零可以确保数字的唯一性和正确性。
代码中的去除前导零
在你的代码中,去除前导零的操作如下:
numbers = [num.lstrip('0') for num in numbers]
这行代码使用列表推导式遍历 numbers 列表,对每个整数调用 lstrip('0') 方法去除前导零。
例子
假设 numbers 列表为 ["001", "010", "100"],经过去除前导零操作后,numbers 列表变为 ["1", "10", "100"]。
心得体会
题目要求替换非数字字符,提取整数,去除前导零,统计不同整数的数量。其中去除前导零是一个容易被忽略的关键步骤。在后面处理字符串和整数相关问题时,需要考虑前导零这一关键问题。