青训营X豆包MarsCode 技术训练营:不同整数的计数问题Python3题解| 豆包MarsCode AI 刷题

71 阅读6分钟

不同整数的计数问题

问题描述

小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

好的,根据编辑区的代码,我将给出完整的题解,包括解题思路、代码实现和测试用例。

解题思路

  1. 字符串处理:遍历字符串 word,将所有非数字字符替换为空格。
  2. 提取整数:将处理后的字符串按空格分割,提取出所有整数。
  3. 去除前导零:去除每个整数的前导零。
  4. 去重:使用集合(set)来存储不同的整数,这样可以自动去重。
  5. 统计不同整数的数量:返回集合的大小。

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)

关键步骤解释

  1. 替换非数字字符

    word = ''.join(c if c.isdigit() else ' ' for c in word)
    

    这行代码使用列表推导式遍历字符串 word,将每个非数字字符替换为空格。

  2. 提取整数

    numbers = word.split()
    

    这行代码使用 split() 方法按空格分割字符串,提取出所有整数。

  3. 去除前导零

    numbers = [num.lstrip('0') for num in numbers]
    

    这行代码使用列表推导式遍历 numbers 列表,对每个整数调用 lstrip('0') 方法去除前导零。

  4. 去重

    unique_numbers = set(numbers)
    

    这行代码使用集合 set 来存储不同的整数,自动去重。

  5. 统计不同整数的数量

    return len(unique_numbers)
    

    这行代码返回集合的大小,即不同整数的数量。

    好的,我们来分析一下代码的时间复杂度和空间复杂度。

时间复杂度

  1. 替换非数字字符

    word = ''.join(c if c.isdigit() else ' ' for c in word)
    

    这行代码使用列表推导式遍历字符串 word,时间复杂度为 O(n),其中 n 是字符串的长度。

  2. 提取整数

    numbers = word.split()
    

    这行代码使用 split() 方法按空格分割字符串,时间复杂度为 O(n),其中 n 是字符串的长度。

  3. 去除前导零

    numbers = [num.lstrip('0') for num in numbers]
    

    这行代码使用列表推导式遍历 numbers 列表,对每个整数调用 lstrip('0') 方法去除前导零。假设 numbers 列表中有 m 个整数,每个整数的长度为 k,则时间复杂度为 O(m * k)

  4. 去重

    unique_numbers = set(numbers)
    

    这行代码使用集合 set 来存储不同的整数,时间复杂度为 O(m),其中 mnumbers 列表的长度。

  5. 统计不同整数的数量

    return len(unique_numbers)
    

    这行代码返回集合的大小,时间复杂度为 O(1)

综合来看,代码的总时间复杂度为 O(n + m * k),其中 n 是字符串的长度,m 是提取出的整数数量,k 是每个整数的平均长度。

空间复杂度

  1. 替换非数字字符

    word = ''.join(c if c.isdigit() else ' ' for c in word)
    

    这行代码生成了一个新的字符串,空间复杂度为 O(n),其中 n 是字符串的长度。

  2. 提取整数

    numbers = word.split()
    

    这行代码生成了一个列表 numbers,空间复杂度为 O(m),其中 m 是提取出的整数数量。

  3. 去除前导零

    numbers = [num.lstrip('0') for num in numbers]
    

    这行代码生成了一个新的列表 numbers,空间复杂度为 O(m),其中 m 是提取出的整数数量。

  4. 去重

    unique_numbers = set(numbers)
    

    这行代码生成了一个集合 unique_numbers,空间复杂度为 O(m),其中 mnumbers 列表的长度。

综合来看,代码的总空间复杂度为 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"]

心得体会

题目要求替换非数字字符,提取整数,去除前导零,统计不同整数的数量。其中去除前导零是一个容易被忽略的关键步骤。在后面处理字符串和整数相关问题时,需要考虑前导零这一关键问题。