Python算法:在列表中搜索差异等于k

时间:2016-06-24 19:59:55

标签: python algorithm

9999

返回差值等于k的计数

number = [5,1,5,3,4]
k = 2

你可以用O(N ^ 2)来解决 在复杂性方面可以更快地完成吗?

它应该返回3,因为有三种情况,差异等于2

cnt = 0
for i in nums:
   for j in nums:
       if i != j:
            if i-j == k:
                cnt += 1
return cnt

4 个答案:

答案 0 :(得分:3)

简单的O(n)解决方案是使用散列表(在python中完美地set)创建索引,并为列表中的每个元素寻找一对。

但是,由于我们关注相同项目的数量,我们应该使用dictCounter来跟踪它们的数量。

from collections import Counter

number = [5,1,5,3,4]
k = 2

index = Counter(number)

for x in number:
  if x + k in index:
    for _ in range(0, index[x + k]):
      print (x, x + k)

答案 1 :(得分:1)

这使用了一台发电机。它仍然是O(N ^ 2),但应该快两倍,因为你只检查一对的一侧。例如,如果数字为[3,1,4],则只检查(3-1),(3-4)和(1-4)而不是(3-1),(3-4), (1-3),(1-4),(4-3),(4-1)。

>>> sum(1 if abs(x - y) == k else 0 
        for n, x in enumerate(number) 
        for y in number[(n + 1):])
3

<强>更新

计数器可用于减小列表的大小。如果数字列表中的某些值m存在nm + k = n,则总计数会增加每个计数的乘积。例如,对于数字= [1,1,2,3,3,3]和k = 2,Counter将是{1:2,2:1,3:3}并且将有6对:2 x 3 =&GT; (1,3)六次。可以使用get来检索m + k的值(如果不存在则默认为零)。

我相信这是O(n),因为时间与数字长度呈线性关系(尽管时间随着范围的增加而略有增加)。

from collections import Counter
import numpy as np

<强>计时

旧方法

%%timeit np.random.seed(0); numbers = np.random.randint(1, 100, 10000)
sum(1 if abs(x - y) == k else 0 
            for n, x in enumerate(numbers) 
            for y in numbers[(n + 1):])
1 loops, best of 3: 17 s per loop

新方法

%%timeit np.random.seed(0); numbers = np.random.randint(1, 100, 10000)  
k = 10
count = 0
c = Counter(numbers)
for key in c:
    count += c[key] * c.get(key + k, 0)
100 loops, best of 3: 3.83 ms per loop

# numbers are 100x larger.
%%timeit np.random.seed(0); numbers = np.random.randint(1, 100, 1000000)  
k = 10
count = 0
c = Counter(numbers)
for key in c:
    count += c[key] * c.get(key + k, 0)
100 loops, best of 3: 380 ms per loop    

答案 2 :(得分:1)

有一个简单的O(n * log(n))解决方案,内存使用量不断增加:

  1. 对列表进行排序:O(n * log(n))
  2. 对于已排序列表中的每个元素k,使用二进制搜索在列表中搜索k + 2<count of elements which is n> * O(log(n))
  3. 因此整体复杂性为O(n * log(n))

    请注意,上面的步骤2可以使用两个指针制作成O(n)复杂度。

答案 3 :(得分:1)

你可以使用itertools。你也可以使用效率更高的发电机。

import itertools

number = [5,1,5,3,4]
k = 2

for item in itertools.combinations(number,2):
   if abs(item[0] - item[1]) == k :
     print item

(或)

一行(下面)中的相同代码:

print [item for item in itertools.combinations(number,2) if abs(item[0] - item[1]) == k ]