问题描述
一个整数如果由相同的数字构成,则称为完美整数。例如:
1
、11
、333
是完美整数。12
、19
、101
是不完美整数。
现在,你需要计算给定区间 [x, y]
中有多少个整数是完美整数。
测试样例
样例1:
输入:
x = 1 ,y = 10
输出:9
样例2:
输入:
x = 2 ,y = 22
输出:10
count = 0
for num in range(x, y + 1):
num_str = str(num)
if len(set(num_str)) == 1:
count += 1
return count
if __name__ == "__main__":
print(solution(1, 10) == 9)
print(solution(2, 22) == 10)
-
函数定义:
solution(x, y)
是一个函数,接受两个参数x
和y
,表示区间的起始和结束。- 函数的目标是计算在区间
[x, y]
中有多少个整数是完美整数。
-
变量初始化:
count = 0
:用于记录完美整数的数量。
-
循环遍历:
for num in range(x, y + 1):
:遍历区间[x, y]
中的每一个整数。num_str = str(num)
:将当前整数转换为字符串,方便后续处理。
-
判断完美整数:
if len(set(num_str)) == 1:
:使用set
数据结构来判断字符串中的字符是否全部相同。如果字符串中的字符全部相同,那么set(num_str)
的长度将为 1。count += 1
:如果当前整数是完美整数,则count
加 1。
-
返回结果:
return count
:返回完美整数的数量。
-
测试代码:
if __name__ == "__main__":
:这部分代码用于测试solution
函数。print(solution(1, 10) == 9)
:测试区间[1, 10]
是否返回 9。print(solution(2, 22) == 10)
:测试区间[2, 22]
是否返回 10。
知识点补充
1. 字符串转换
在代码中,我们将整数转换为字符串:
这样做的好处是可以方便地对整数的每一位进行操作。例如,我们可以使用字符串的 len()
方法来获取字符串的长度,或者使用 set()
来判断字符串中的字符是否全部相同。
2. 集合(Set)
在代码中,我们使用了 set
数据结构:
set
是一种无序且不重复的集合。当我们把一个字符串转换为 set
时,字符串中的重复字符会被自动去重。因此,如果字符串中的字符全部相同,那么 set(num_str)
的长度将为 1。
3. 循环与条件判断
代码中使用了 for
循环来遍历区间 [x, y]
中的每一个整数,并使用 if
条件判断来检查当前整数是否为完美整数。
这种结构在编程中非常常见,用于遍历一组数据并对每个数据进行某种操作或判断。
4. 时间复杂度分析
当前代码的时间复杂度为 O((y - x) * d)
,其中 d
是整数的平均位数。因为我们需要遍历区间 [x, y]
中的每一个整数,并对每个整数进行字符串转换和集合操作。
- 字符串转换:
str(num)
的时间复杂度为O(d)
,其中d
是整数的位数。 - 集合操作:
set(num_str)
的时间复杂度为O(d)
,因为需要遍历字符串中的每一个字符。
因此,总的时间复杂度为 O((y - x) * d)
。
5. 空间复杂度分析
当前代码的空间复杂度为 O(d)
,其中 d
是整数的平均位数。因为我们需要存储字符串和集合。
- 字符串:
num_str
的空间复杂度为O(d)
。 - 集合:
set(num_str)
的空间复杂度为O(d)
。
优化思路
虽然当前代码已经能够正确解决问题,但我们可以考虑一些优化思路:
-
减少字符串转换:
- 字符串转换和集合操作可能会带来一定的性能开销。我们可以考虑直接对整数进行操作,而不是转换为字符串。
-
减少集合操作:
- 如果整数的位数较多,集合操作可能会带来较大的开销。我们可以考虑使用其他方法来判断整数是否为完美整数。
-
提前终止:
- 如果我们在遍历过程中发现某个整数不是完美整数,可以提前终止对该整数的进一步处理,从而减少不必要的计算。
总结
当前代码通过遍历区间 [x, y]
中的每一个整数,并使用字符串和集合操作来判断整数是否为完美整数。代码结构清晰,逻辑正确,但可以通过一些优化来提高性能。