我正在task上寻找有效的解决方案
你知道K是数字中的位数之和,N是数字中的位数。
所以你要找到所有数的计数,最小数和最大数。
此外,它必须是排序的数字。例如:
145 - sorted number, because 4 > 1, and 5 > 4.
382 - not sorted number, because 3 < 8, but 8 > 2.
一切都必须符合问题的情况。
我是这么做的:
def find_all(sum_dig, digs):
min_num = 10000000000000000
max_num = -1
count = 0
for i in range((10 ** digs // 10), 10 ** digs):
summ = 0
for j in range(len(str(i))):
summ += int((str(i))[j])
if summ == sum_dig and str(i) == ''.join(sorted(str(i))):
count += 1
if i > max_num:
max_num = i
if i < min_num:
min_num = i
if count == 0:
return []
else:
return [count, min_num, max_num]
但是这段代码运行起来非常慢,我得到了错误Execution Timed Out (12000 ms)
你能告诉我有什么方法能使它更有效吗?
任何建议都不胜感激!
4条答案
按热度按时间5cnsuln71#
我们可以不对从
10^(digs-1)
到10^digs
的每一个数字进行迭代,这样会有一个很宽的搜索空间,我们可以通过从最左边的数字到最右边的数字以非递减的方式(或者如果你喜欢的话,从右到左以非递增的方式)一个接一个地添加数字来进行迭代。Reference我在网站上测试了下面的python代码,它似乎解决了这个任务。
我认为这段代码的时间复杂度还可以改进。
如果你想优化它,你可以尝试搜索自顶向下的动态规划和记忆技术。
yqkkidmi2#
下面是我对每个所需值的函数,它似乎通过了测试(如果分区计数为零,则返回空列表)。
对于结果的数目,我们可以修改具有受限部分数目的划分的递归:取(1)将
n-k
划分为具有至多l-1
的最大部分的k
部分的所有分区的计数,并将其相加(2)将n-1
划分为具有至多l
的最大部分的k-1
部分的所有划分的计数。(对于(1)中的每个部分添加1,总共k
1
s。对于(2)中的每个分区,添加一个部分1
。)O(n, k)
搜索空间。对于最小的数字,我们可以从左到右使用贪婪的
O(n)
方法,总是选择最小的数字。对于最大的,我想不出比递归更好的方法了,递归根据当前状态限制数字的选择。
O(n, k)
.bb1commentedO(n)
解决方案。vof42yt13#
你可以使用递归的方法,一次收集一个数字到一个列表中,直到它达到指定的总和,如果它的总和正确匹配,返回值。然后,我们可以大量使用过滤来避免测试我们知道将超过目标总和或不是按升序排列的数字,减少我们必须大量检查的潜在值的数量。
我在网站上测试过,它确实在规定的时间内通过了所有测试。
find_all
函数只接受结果并将其转换为质询所需的格式。gxwragnw4#
找出所有给予总和等于s的数