解题思路解析
在这个问题中,我们的目标是从1到给定整数N中找出一个最大的“关键数”。关键数的定义是:该数至少能被其某一位数字整除。换句话说,对于每个数,我们需要检查它的每一位数字,如果该数字能整除这个数,那么这个数就是关键数。
思路总结:
- 从大到小遍历:我们从N开始向下遍历到1,目的是找到最大的关键数,因此优先遍历较大的数可以确保我们第一时间找到最大值。
- 位数检查:对于每个数,我们需要逐位检查它的数字。具体来说,对于一个数,我们提取出它的每一位数字,检查它是否能整除这个数。
- 条件判断:如果某个数字不为0且能整除这个数,我们就认为这个数是一个关键数,直接返回这个数。
- 边界条件:每个数至少有一位数字是1,因此理论上每个数都能被它的某一位数字整除,除非数值为0(但题目中不涉及0的情况)。
具体步骤
- 初始化:我们从N开始逐步向下检查每个数。
- 转换为字符串:将每个数转换为字符串,方便提取每一位数字。
- 检查每位数字:对于转换后的字符串,逐个检查每位数字。如果某位数字能整除该数,我们认为该数是关键数。
- 返回结果:一旦找到符合条件的数,就返回这个数。
代码实现
pythonCopy Code
def solution(N: int) -> int:
# 从 N 开始向下遍历到 1
for num in range(N, 0, -1):
# 将数字转换为字符串,提取每一位数字
digits = [int(d) for d in str(num)]
# 检查每一位数字是否能整除 num
if any(digit != 0 and num % digit == 0 for digit in digits):
return num
# 如果没有找到关键数,返回 1(理论上不会执行到这里)
return 1
if __name__ == '__main__':
print(solution(N = 499) == 497) # 示例测试
print(solution(N = 1000) == 1000)
print(solution(N = 785) == 785)
代码解析
-
for num in range(N, 0, -1):- 这个循环从N开始,逐步减小,直到1。它确保我们优先检查较大的数字,因为我们寻找的是最大的关键数。
-
digits = [int(d) for d in str(num)]:- 将当前的数字
num转换为字符串,并利用列表推导式提取每一位数字。这样,我们就可以逐个检查数字的每一位。
- 将当前的数字
-
if any(digit != 0 and num % digit == 0 for digit in digits):any()函数检查是否存在至少一个数字能整除num。在这个条件中,我们排除了数字为0的情况(因为数字0无法作为除数)。
-
返回结果:
- 一旦找到满足条件的数字,立即返回该数。如果遍历完所有数没有找到(理论上不可能出现这种情况,因为任何数都能被1整除),则返回1。
解题思路详细解析
这个问题的本质是从一个整数N开始,检查每个数是否满足“关键数”的条件。通过从大到小的遍历方式,确保我们能在最短时间内找到最大的关键数。
1. 从大到小遍历的理由
为了提高效率,我们希望尽快找到最大的关键数。因此,从N开始向下遍历到1,避免了不必要的检查。假如我们从1开始遍历,可能会检查到很多不必要的数,而这些数显然不是我们需要的最大值。
2. 检查每一位数字
每个数的关键性取决于它的数字是否能整除该数。例如,对于数字496,十位数字是4,个位数字是6,我们检查这些数字,发现4能整除496。因此,496就是一个关键数。同理,其他数如497,498也需要检查它们的每一位数字。
3. 排除数字0
由于数字0不能作为除数,因此在检查每位数字时,我们要排除数字0的情况。这个通过digit != 0来保证。如果数字包含0,直接跳过这个数字作为除数的情况。
4. 时间复杂度分析
时间复杂度主要受两部分影响:
- 遍历每个数:从N到1的遍历,因此需要O(N)的时间。
- 检查每位数字:对于每个数字,最多需要检查它的位数。假设N的最大位数为d,则对于每个数,我们需要进行O(d)的操作来检查每一位数字。
因此,总体时间复杂度是O(N * d),其中N是给定的整数,d是N的位数。假设N的最大位数为log(N),那么时间复杂度近似为O(N * log(N))。
5. 空间复杂度分析
空间复杂度主要由存储数字的每一位所需的空间决定。对于每个数,我们需要将它转换为字符串,并存储每一位数字,因此空间复杂度是O(d),其中d是N的位数。
示例解析
示例1:输入N = 499
从499开始,逐个检查:
- 499:数字4、9、9,都不能整除499。
- 498:数字4、9、8,都不能整除498。
- 497:数字4、9、7,数字4能整除497,因此497是最大的关键数。
输出为497。
示例2:输入N = 1000
从1000开始:
- 1000:数字1、0、0、0,数字1能整除1000。 因此,1000是一个关键数。
输出为1000。
示例3:输入N = 785
从785开始:
- 785:数字7、8、5,数字7能整除785。 因此,785是一个关键数。
输出为785。
总结
通过从大到小遍历并逐位检查数字是否能整除给定数,我们可以高效地找到最大的关键数。该方法在解决类似问题时具备较好的性能,并且能保证在大多数输入情况下都能迅速给出正确答案。