社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何提高python代码的时间效率?

Ganesh • 4 年前 • 848 次点击  

我试图执行的程序有以下问题声明:

程序必须接受n个整数,其中包含从1到n的整数 以任何顺序复制。程序必须打印丢失的 给定整数中从1到n的整数,升序为 输出。

例子:

输入: 5个

2 5 5 1 1年

输出:34

说明:5个整数中缺少整数3和4 2 5 5 11号。因此3和4被打印为输出

我的代码:

def modusoperandi(n, t):
    if str(n) not in t:
        yield n 

n = int(input())
t = tuple(sr for sr in input().split())
for i in range(1,n+1):
    for j in modusoperandi(i,t):
        print(j,end=' ')

但是,我的代码未能通过所有测试用例,因为对于输入量巨大的测试用例执行需要相当长的时间[需要500毫秒以上,这是时间限制]。

我试着用 时间 方法。特别的是,当元组中的元素数量增加时,对于给定的n,执行时间也会增加。我更喜欢元组而不是列表,因为它应该更有效。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/46979
 
848 次点击  
文章 [ 4 ]  |  最新文章 4 年前
Michael Veksler
Reply   •   1 楼
Michael Veksler    4 年前

你应该考虑你的解决方案的复杂性(这是非常糟糕的):

def modusoperandi(n, t):
    # Since 't' is a tuple, the complexity of 'not in t' is O(len(t))
    # This makes the overall complexity of this function O(len(t))
    if str(n) not in t:
        yield n 

n = int(input())
t = tuple(sr for sr in input().split()) # O(len(t))
for i in range(1,n+1):  # O(n) iterations

    # 0 or 1 iteration, but the call to 'modusoperandi' is O(len(t))
    for j in modusoperandi(i,t):  
        print(j,end=' ')

总复杂度o(n*len(t))。这不是一个很好的复杂性。你需要一个在输入中是线性的复杂度。有两种方法:

  1. 使用哈希表标记所有访问的整数,并且 set 是这样一个哈希表。不幸的是哈希表有一些缺点。
  2. 既然有 n 条目和数字在1..n范围内,那么使用特征向量是非常有效的 values_encountered ,其中 values_encountered[i] True 如果且仅当 i 遇到值。对于这种类型的大输入,这种解决方案可能比集合运行得更快,并且消耗更少的内存。

是的。

import numpy as np
n = int(input())

values_encountered = np.zeros(n+1, dtype=bool)     # O(n)
values_encountered[[int(i) for i in input().split()]] = True # O(n)
# Or:
# values_encountered[list(map(int, input().split()))] = True

values_missing= (values_encountered == False) # O(n)
values_missing[0] = False
print(*list(*values_missing.nonzero())) # O(n)
Andrej Kesely
Reply   •   2 楼
Andrej Kesely    4 年前
n = '5'
i = '2 5 5 1 1'

def compute(n, i):
    s1 = set(range(1, n+1))
    yield from sorted(s1.difference(i))


for val in compute(int(n), map(int, i.split()) ):
    print(val, end=' ')

印刷品:

3 4 
Alain T.
Reply   •   3 楼
Alain T.    4 年前

关键是使用一个集合来检查输入字符串中是否存在预期的数字。不过,您不需要将输入转换为整数。另一种方法是将序列号生成为字符串。

nums    = input().split()
numSet  = set(nums)
missing = " ".join(str(n) for n in range(1,len(nums)+1) if str(n) not in numSet)

print(missing) # 3 4

对于这个特定的问题,有一个比使用集合更快的选择,因为您可以创建一个具有已知(和合理)大小的标志数组:

numbers = input().split()
present = [False]*len(numbers)
for n in numbers: present[int(n)-1] = True
missing = " ".join(str(n+1) for n,seen in enumerate(present) if not seen)
AKX
Reply   •   4 楼
AKX    4 年前

您将希望将现有的数字转换为 int 埃格斯,然后把它们放在 set ;集合对于计算给定值是否为成员非常有效。

n = int(input())
extant = set(int(n) for n in input().split())
for i in range(1, n + 1):
    if i not in extant:
        print(i, end=" ")