小C的好数 Python题解 | 豆包MarsCode AI刷题

54 阅读3分钟

小C的好数

问题描述

小C对“好数”非常感兴趣,她定义一个不含前导零的正整数为“好数”,如果它的所有数位最多包含两种不同的数字。例如,数字 2323239111,和 101 都是好数。现在小C想知道,从1到nn之间有多少个好数。

例如:当n=110时,所有的1位数、2位数,以及一些3位数(如 100101)都是好数,一共有102个。


测试样例

样例1:

输入:n = 110
输出:102

样例2:

输入:n = 1000
输出:352

样例3:

输入:n = 1
输出:1

解题思路

这道题其实不需要用到复杂的算法,遍历每一个数,判断它是否是好数即可。具体的实现步骤如下:

  1. 从 1 到 n,逐一遍历每个数字。
  2. 将数字转换为字符串,利用集合来判断该数字的数位包含多少种不同的数字。
  3. 如果集合的大小小于等于2,则说明这是一个好数,将计数器加一。
  4. 最后输出计数器的值。

关键点:

  • 使用集合 set 来去重数位,避免重复计算相同的数字。
  • 对于较大的数字,计算时可能会有性能问题,考虑到数字的位数增大,检查每个数字的位数会稍显繁琐。

Python代码

def solution(n: int) -> int:
    # write code here
    count = 0
    for i in range(1,n+1):
    # 将数字转换为字符串形式,方便提取各个位数
        num = str(i)
        same = set(num)
        if len(same) <= 2:
            count += 1
    return count

if __name__ == '__main__':
    print(solution(110) == 102)
    print(solution(1000) == 352)
    print(solution(1) == 1)
    print(solution(890000) == 4375)

代码解释

  • solution(n) :这个函数用于计算从 1 到 n 之间“好数”的数量。

    • 使用一个 for 循环遍历每个数字,从 1 到 n。
    • 对于每个数字,首先将其转化为字符串形式,然后利用 Python 的集合 set 来去重,从而得到该数字包含的不同数字的个数。
    • 如果不同的数字个数小于等于 2,则说明这是一个“好数”,我们将计数器 count 加 1。
  • set(num) :这里将数字 num 转换为字符串,并传入 set 中。set 会自动去除重复的元素,因此它的大小就代表了数字中不同的数字个数。

  • 最终返回 count:最终返回符合条件的“好数”的总数。

小缺点(思考):虽然代码的逻辑很清晰易懂,但在最坏情况下,时间复杂度为 O(n * d),其中 n 是输入的范围,d 是数字的位数。在最坏的情况下,d 约为 log(n),因为 n 越大,其位数也越多。因此,总体的时间复杂度是比较高的。 对于较小的 n,比如测试用例中的 110 或 1000,以上代码的性能完全可以接受。但是当 n 非常大时(例如数百万甚至上亿),代码的效率就会受到影响。这时,需要更加优化的算法来解决。