我有以下数字列表 -
L = [ 1430185458, 1430185456, 1430185245, 1430185246, 1430185001 ]
我正在尝试确定哪些数字在" 2"范围内?彼此。列表将在我收到时未分类。
如果有2个范围内的数字,我必须返回" 1"收到完全相同的位置号码。
我能够达到预期的效果,但代码运行速度非常慢。我的方法涉及排序列表,使用两个指针迭代它并连续比较它。我将有数百万条记录作为单独的列表出现。
试着看看解决这个问题的最佳方法是什么。
编辑 - 道歉,因为我离开了一段时间。 List中可以包含任意数量的元素,范围从1到n。想法是在收到完全相同的位置编号时返回0或1。我无法发布我实现的实际代码,但这里是伪代码。
一个。创建新列表作为列表列表,第二部分为每个元素为0。我们假设在彼此的范围内没有数字。
[[1430185458,0], [1430185456,0], [1430185245,0], [1430185246,0], [1430185001,0]]
湾排序原始列表
℃。比较第一个元素到第二个,第二个到第三个,依此类推,直到达到列表末尾,并且当差值小于或等于2时,在步骤a到1中更新相应的第二个元素。
[[1430185458,1], [1430185456,1], [1430185245,1], [1430185246,1], [1430185001,0]]
答案 0 :(得分:2)
目标是快速,因此可能意味着O(N)算法。构建NxN差异矩阵是O(N ^ 2),因此根本不好。排序是O(N * log(N)),因此也是如此。假设字典插入和查找的平均情况O(1)行为,以下是O(N)算法。它会在几秒钟内通过一百万个随机整数列表。
def in_range (numbers) :
result = [0] * len(numbers)
index = {}
for idx, number in enumerate(numbers) :
for offset in range(-2,3) :
match_idx = index.get(number+offset)
if match_idx is not None :
result[match_idx] = result[idx] = 1
index[number] = idx
return result
的更新强>
我必须返回" 1"收到完全相同的位置号码。
如果输入[[1,1],[2,1],[5,0]]
,问题的更新会要求提供[1,2,5]
表单的列表。我没那样做。相反,我的代码会返回给定[1,1,0]
的{{1}}。与[1,2,5]
列表相比,生成简单的0/1列表的速度提高了约15%。可以使用[[value,in_range],...]
:
zip
答案 1 :(得分:0)
我认为这可以满足您的需求(process()修改列表L)。但很可能它仍然是可以优化的:
def process(L):
s = [(v,k) for k,v in enumerate(L)]
s.sort()
j = 0
for i,v_k in enumerate(s):
v = v_k[0]
while j < i and v-s[j][0]>2:
j += 1
while j < i:
L[s[j][1]] = 1
L[s[i][1]] = 1
j += 1