小于最大数的倍数

时间:2014-11-09 23:07:58

标签: python algorithm

对于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. 

如何优化此代码?

2 个答案:

答案 0 :(得分:2)

3和5具有相同的倍数,如15。

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

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

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

假设你想要得到3的倍数小于100,你可以通过除以楼层(100/3)来做到这一点,同样适用于5,楼层(100/5)。 现在要获得小于100的3和5的乘法,你必须添加它们,并减去两者的倍数。在这种情况下,减去15的乘数。 因此,对于3和5的倍数,小于100的答案是楼层(100/3)+楼层(100/5) - 楼层(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)

答案 1 :(得分:0)

如果您需要的只是列表的长度,那么您最好使用计数而不是创建另一个列表。

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