如何降低给定python代码的时间复杂度?

时间:2018-08-09 17:32:56

标签: python-3.x time-complexity

我有这个python程序,用于计算给定数字的“平方免费数”。我遇到了有关时间复杂度的问题,这是我在在线编译器中收到“超过时间限制”错误。

number = int(input())
factors = []
perfectSquares = []
count = 0
total_len = 0

# Find All the Factors of the given number
for i in range(1, number):
if number%i == 0:
    factors.append(i)

# Find total number of factors        
total_len = len(factors)

for items in factors:
    for i in range(1,total_len):
  # Eleminate perfect square numbers
    if items == i * i:
        if items == 1:
            factors.remove(items)
            count += 1
        else:
            perfectSquares.append(items)
            factors.remove(items)
            count += 1

# Eleminate factors that are divisible by the perfect squares 
for i in factors:
    for j in perfectSquares:
    if i%j == 0:
        count +=1

# Print Total Square Free numbers
total_len -= count 
print(total_len)

如何减少该程序的时间复杂度?那该如何减少for循环,使程序以较小的时间复杂度执行?

2 个答案:

答案 0 :(得分:1)

首先,您只需要检查for i in range(1, number/2):,因为number/2 + 1和更大的值不能成为因素。

第二,您可以计算出可能是次线性时间因素的理想平方数:

squares = []
for i in range(1, math.floor(math.sqrt(number/2))):
    squares.append(i**2)

第三,您可以搜索因子,当找到一个因子时,检查它是否不能被正方形整除,然后将其添加到因子列表中。

这种方法将为您节省for items in factors嵌套循环块以及下一个块的所有时间。我不确定是否一定会更快,但是浪费更少。

答案 1 :(得分:0)

降低 Python 代码时间复杂度 (TC) 的算法技术。

为了降低代码的时间复杂度,无论何时何地都非常有必要减少循环的使用。

我会将您代码的逻辑部分分为 5 个部分,并建议对每个部分进行优化。

第 1 部分 - 变量声明和输入

number = int(input())
factors = []
perfectSquares = []
count = 0
total_len = 0

您可以轻松地省略完全平方数、count 和 total_length 的声明,因为它们不是必需的,如下所述。这将降低代码的时间和空间复杂度。

此外,您可以使用 Fast IO,以加快 INPUTS 和 OUTPUTS 这是通过使用“stdin.readline”和“stdout.write”来完成的。

第 2 部分 - 查找所有因素

for i in range(1, number):
    if number%i == 0:
        factors.append(i)
  1. 在这里,您可以使用列表理解技术来创建因子列表,因为列表理解比循环语句更快。
  2. 此外,您可以迭代直到数字的平方根,而不是循环直到数字本身,从而以指数方式降低时间复杂度。 上面的代码部分可以简化为...

应用 '1' hack 后

factors = [for i in range(1, number) if number%i == 0]

应用 '2' hack 后 - 使用 from_iterable 在列表理解中的每次迭代中存储 1 个以上的值

factors = list( chain.from_iterable(
  (i, int(number/i)) for i in range(2, int(number**0.5)+1)
    if number%i == 0
  ))

第 3 部分 - 消除完全平方

# Find total number of factors        
total_len = len(factors)

for items in factors:
    for i in range(1,total_len):
  # Eleminate perfect square numbers
    if items == i * i:
        if items == 1:
            factors.remove(items)
            count += 1
        else:
            perfectSquares.append(items)
            factors.remove(items)
            count += 1

其实你可以完全省略这部分,只需要在第 2 节中添加额外的条件,即 ... type(i**0.5) != int,以消除那些具有整数平方根的数字,因此是完全平方数他们自己。 实现如下....

factors = list( chain.from_iterable(
  (i, int(number/i)) for i in range(2, int(number**0.5)+1)
    if number%i == 0 and type(i**0.5) != int
  ))

第 4 部分 - 我认为不需要此部分,因为 Square Free Numbers 没有这样的限制

第 5 部分 - 完成计数、打印计数

绝对不需要计数器,您可以计算因子列表的长度,并将其用作计数。

优化代码

方式 1 - 稍微快一点

number = int(input())

# Find Factors of the given number
factors = []
for i in range(2, int(number**0.5)+1):
    if number%i == 0 and type(i**0.5) != int:
        factors.extend([i, int(number/i)])

print([1] + factors)

方式 2 - 优化编程 - 非常快

from itertools import chain 
from sys import stdin, stdout

number = int(stdin.readline())
factors = list( chain.from_iterable(
  (i, int(number/i)) for i in range(2, int(number**0.5)+1)
    if number%i == 0 and type(i**0.5) != int
  ))

stdout.write(', '.join(map(str, [1] + factors)))