已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。
10小时前关闭。
Improve this question
**问题:**给定一个未排序元素的列表,我们必须找到最长连续元素序列的长度。
时间复杂度:O(N)
用于Ex:[4,7,1,100,28,2,3]
**输出:**4,因为最长的连续元素序列是上述列表中的[1,2,3,4]
View Problem Statement
我用 Python 写了代码。我使用了set和**map(defaultdict)**来解决这个问题。
from collections import defaultdict as maps
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
nums = set(nums); # to remove duplicates
n = len(nums);
if n == 0: return 0;
if n == 1: return 1;
present = maps(int);
# Inserting values into map (defaultdict) as key
for i in nums:
present[i] = 1; # to check for presence of element
i = 0; curr = 0; cnt, maxx = 0, 0; visset = {i for i in nums}
while n > 0:
#I had to use this while loop since the for-loop below will get interrupted if we make any changes to the iterating set.
cnt = 1;
for ind in visset:
curr = ind; n -= 1;
visset.remove(ind); break; #remove is O(1) complexity for set
# values less than curr::
curr, temp = curr, curr;
while n > 0:
if present[curr - 1]:
curr -= 1; n -= 1;
visset.remove(curr); cnt += 1; #remove is O(1) complexity for set
else:
break;
# values greater than curr::
while n > 0:
if present[temp + 1]:
temp += 1; n -= 1;
visset.remove(temp); cnt += 1; #remove is O(1) complexity for set
else:
break;
maxx = max(cnt, maxx);
maxx = max(cnt, maxx);
return maxx
for more reference and runtime
有人能解释一下为什么这段代码的运行时间比预期的要高吗?
**UPDATE:**这个程序的运行时间大约是7000ms,如果我用字典替换set,并且在set的情况下使用del dictt[i]而不是remove(),那么运行时间将下降到2000ms
3条答案
按热度按时间ia2d9nvy1#
它在像
list(range(0, 200000, 2))
这样的输入上很慢。这样做100000次:不是删除速度慢,而是
for
循环迭代找到ind
,正如这里所解释的。总共需要2次时间。使用
ind = visset.pop()
代替,它针对重复删除任意元素进行了优化。或者您可以使用collections.OrderedDict
而不是您的设备。由于它的额外的链表,它的快速为您的风格找到一个和删除它。这里有一个替代方法,你也可以考虑。
基于我们可以测试前一个数字和下一个数字是否在列表中的事实,我们可以构建并跟踪项目的运行。
基于
timeit
,这将在大约1/4秒内完成一百万个随机整数的列表。hfyxw5xn2#
问题可能源于
for ind in visset
。我以前也是这样做的,但我从来没有想过要这样做。在从集合中删除元素之后,迭代集合似乎会涉及一些开销。也许不删除项的解决方案会运行得更快:
wz3gfoph3#
你的在leetcode上没有修改就通过了,但它的速度较慢。下面是对相同代码的简化,它的性能略高于平均水平:
您确实有很多不必要的数据结构,并且在值甚至没有使用的地方复制Map。我把它们都换成了一套。