【问题标题】:Number of multiples less than the max number小于最大数的倍数
【发布时间】:2014-11-09 23:07:58
【问题描述】:

针对以下 SingPath 上的问题:

Given an input of a list of numbers and a high number, 
return the number of multiples of each of 
those numbers that are less than the maximum number.
For this case the list will contain a maximum of 3 numbers 
that are all relatively prime to each
other.

这是我的代码:

def countMultiples(l, max_num):
    counting_list = []
    for i in l:
        for j in range(1, max_num):
            if (i * j < max_num) and (i * j) not in counting_list:
                counting_list.append(i * j)
    return len(counting_list)

虽然我的算法可以正常工作,但当最大数量太大时它会卡住

>>> countMultiples([3],30)
9      #WORKS GOOD

>>> countMultiples([3,5],100)
46     #WORKS GOOD

>>> countMultiples([13,25],100250)
Line 5: TimeLimitError: Program exceeded run time limit. 

如何优化这段代码?

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    3 和 5 有一些相同的倍数,比如 15。

    你应该去掉那些倍数,你会得到正确的答案

    另外你应该检查包含排除原则https://en.wikipedia.org/wiki/Inclusion-exclusion_principle#Counting_integers

    编辑: 问题可以在恒定时间内解决。如前所述,解决方案是包含 - 排除原则。

    假设你想得到小于 100 的 3 的倍数,你可以通过除 floor(100/3) 来实现,同样适用于 5, floor(100/5)。 现在要获得小于 100 的 3 和 5 的倍数,您必须将它们相加,然后减去两者的倍数。在这种情况下,减去 15 的倍数。 所以小于 100 的 3 和 5 的倍数的答案是 floor(100/3) + floor(100/5) - floor(100/15)。 如果你有两个以上的数字,它会变得有点复杂,但同样的方法也适用,更多检查https://en.wikipedia.org/wiki/Inclusion-exclusion_principle#Counting_integers

    EDIT2:

    循环变体也可以加速。 您当前的算法在列表中附加多个,这非常慢。 您应该切换内部和外部 for 循环。通过这样做,您将检查是否有任何除数除数,然后您得到除数。

    所以只需添加一个布尔变量,它会告诉您是否有任何除数除以数字,并计算变量为真的次数。

    所以它会是这样的:

    def countMultiples(l, max_num):
      nums = 0
      for j in range(1, max_num):
        isMultiple = False
        for i in l:  
          if (j % i == 0):
        isMultiple = True
        if (isMultiple == True):
          nums += 1
      return nums
    
    print countMultiples([13,25],100250)
    

    【讨论】:

    • 我没有投反对票,实际上我对你的答案投了赞成票。我讨厌人们在没有给出任何解释的情况下投反对票
    • 谢谢@Aleksandar,只是好奇你在哪里学的这个?一些算法课程?
    • 我院系的组合和算法课程,也有很多解决问题的经验,主要是针对这类问题的欧拉投影。
    【解决方案2】:

    如果列表的长度是你所需要的,你最好用一个计数而不是创建另一个列表。

    def countMultiples(l, max_num):
        count = 0
        counting_list = []
        for i in l:
            for j in range(1, max_num):
                if (i * j < max_num) and (i * j) not in counting_list:
                    count += 1
        return count
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 2022-11-27
      • 2011-12-17
      • 2021-07-16
      • 1970-01-01
      • 2016-11-19
      相关资源
      最近更新 更多