Python 数组中的重复对
给定一个索引为零、整数为N的数组,数组中不同位置的元素相等。一对索引Python 数组中的重复对,python,arrays,count,Python,Arrays,Count,给定一个索引为零、整数为N的数组,数组中不同位置的元素相等。一对索引(P,Q),这样0您可以执行的操作与此类似: 这是一种天真的方法: def function(arr) : count = 0 n = len(arr) i = 0 for i in range(n): for j in range(i+1,n): if arr[i]==arr[j]: count+=1 return count 这是一
(P,Q)
,这样0您可以执行的操作与此类似:
这是一种天真的方法:
def function(arr) :
count = 0
n = len(arr)
i = 0
for i in range(n):
for j in range(i+1,n):
if arr[i]==arr[j]:
count+=1
return count
这是一种更优化的方法,您可以尝试:
def function(arr) :
mp = dict()
n = len(arr)
for i in range(n):
if arr[i] in mp.keys():
mp[arr[i]] += 1
else:
mp[arr[i]] = 1
ans = 0
for it in mp:
count = mp[it]
ans += (count * (count - 1)) // 2
return ans
您可以使用来计算每个整数的出现次数,
然后与n=count
和k=2
一起使用,以获得每个整数的这类对数,并简单求和:
从集合导入计数器
从数学导入梳
def功能(arr):
返回和(num的comb(count,2),计数器中的count(arr.items())
打印(函数([1,2,3,6,3,6,3,6,3,2]))
原因是math.comb(count,2)
正是成对的数目,即您选择的count
中的任何2
元素,无论其顺序如何,都是一对:前者是p
,后者是Q
编辑:添加了timeit
benchmarks:
下面是一个完整的示例,您可以通过测试来比较这两种方法的性能:
从timeit导入timeit
从随机导入randint
从收款进口柜台
从数学导入梳
带梳齿的def(arr):
返回和(num的comb(count,2),计数器中的count(arr.items())
带_循环(arr)的def:
mp=dict()
n=长度(arr)
对于范围(n)中的i:
如果mp.keys()中的arr[i]:
mp[arr[i]]+=1
其他:
mp[arr[i]]=1
ans=0
对于mp中的it:
count=mp[it]
ans+=(计数*(计数-1))//2
返回ans
a=[randint(11000)表示范围内(10000)]
time1=timeit('with_loops(a)”,globals=globals(),number=1000)
time2=timeit('with_comb(a'),globals=globals(),number=1000)
打印(时间1)
打印(时间2)
打印(时间1/2)
输出(在我的笔记本电脑上):
arr是否类似于[1,2]
或[[1,2],[3,4]
?@AnnZen数组由N个整数组成,因此我假设第一个选项?至于2,只要在需要更新N
@a0142204时使用len(arr)
。谢谢。我也考虑过这个问题,但我被一个非常愚蠢的问题卡住了:与上面@gagangaur提出的第二种方法相比,这有多最优?@a0142204查看我的基准测试(我想自己试着运行),在我的笔记本电脑上,我的方法运行速度似乎快了x3.6倍。@a0142204在repl上。它似乎是相同的(甚至是x4.1):
def function(arr) :
mp = dict()
n = len(arr)
for i in range(n):
if arr[i] in mp.keys():
mp[arr[i]] += 1
else:
mp[arr[i]] = 1
ans = 0
for it in mp:
count = mp[it]
ans += (count * (count - 1)) // 2
return ans
2.9549962
0.8175686999999998
3.6143705110041524