Python 3.x 求和等于m的第k个最小数

Python 3.x 求和等于m的第k个最小数,python-3.x,Python 3.x,我正在寻找的示例: Input: M = 5, K = 3 Output: 23 Sequence of numbers starting from 1 with digit sum as 5 is as follows: 5 14 23 32 41 So 3rd smallest number is 23 我的方法,它给了我我想要的,但我不认为这是最好的方法。当K>1时,会发生许多不必要的计算。在我的解决方案中,我指的是M作为num,K作为position 有人能帮我重构代码吗?或者可以提出

我正在寻找的示例:

Input: M = 5, K = 3
Output: 23
Sequence of numbers starting from 1 with digit sum as 5 is as follows:
5
14
23
32
41
So 3rd smallest number is 23
我的方法,它给了我我想要的,但我不认为这是最好的方法。当K>1时,会发生许多不必要的计算。在我的解决方案中,我指的是M作为num,K作为position

有人能帮我重构代码吗?或者可以提出一种全新的方法来实现。如果需要更多信息,请发表评论。

我不认为这是最佳解决方案,但至少是一种改进:

def sum_digits(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

def kthsmallest(m, k):
    position = 1
    number = m

    while True:
        if sum_digits(number) == m:
            if position == k:
                return number
            position += 1
        number += 1
时间结果:

# new
> timeit.timeit('kthsmallest(5, 3)', setup=...)
7.015244078

# original
> timeit.timeit('kthsmallest(5, 3)', setup=...)
15.881711267
对于更大的m值,这仍然非常缓慢:

sum_digits函数的功劳在于。

我认为这不是最理想的解决方案,但至少是一种改进:

def sum_digits(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

def kthsmallest(m, k):
    position = 1
    number = m

    while True:
        if sum_digits(number) == m:
            if position == k:
                return number
            position += 1
        number += 1
时间结果:

# new
> timeit.timeit('kthsmallest(5, 3)', setup=...)
7.015244078

# original
> timeit.timeit('kthsmallest(5, 3)', setup=...)
15.881711267
对于更大的m值,这仍然非常缓慢:


这是对已提供答案的非常粗略的改进

在我的系统上,这是两次调用所用的时间-

λ test.py
1.0293785
142.652913

这是一个轻微的加速,但一旦您在数字中寻找更高的数字和,它将显著减速,因为我们基本上已经根据一些已知的数字属性硬编码了要跳过的数字。使用timeit需要一段时间,但当我按原样运行代码时,这几乎是瞬间的

这是对已经提供的答案的一个非常粗糙的改进

在我的系统上,这是两次调用所用的时间-

λ test.py
1.0293785
142.652913

这是一个轻微的加速,但一旦您在数字中寻找更高的数字和,它将显著减速,因为我们基本上已经根据一些已知的数字属性硬编码了要跳过的数字。使用timeit需要一段时间,但在我按原样运行代码时几乎是瞬间的

timeit默认使用数字参数100000,这是要运行的测试数,因此,您的timeit测试比按原样运行代码花费的时间更长。@我忘记了默认值那么大:|我假设它是一个小得多的数字。默认情况下,它接受数字参数100000,这是要运行的测试数,因此,您的timeit测试比按原样运行代码花费的时间更长。@Monica我忘记了默认值是那么大:|我假设它是一个小得多的数字