-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
count-equal-and-divisible-pairs-in-an-array.py
80 lines (67 loc) · 2.08 KB
/
count-equal-and-divisible-pairs-in-an-array.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Time: O(nlogk + n * sqrt(k))
# Space: O(n + sqrt(k)), number of factors of k is at most sqrt(k)
import collections
# math, number theory
class Solution(object):
def countPairs(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
def gcd(x, y):
while y:
x, y = y, x%y
return x
idxs = collections.defaultdict(list)
for i, x in enumerate(nums):
idxs[x].append(i)
result = 0
for idx in idxs.itervalues():
gcds = collections.Counter()
for i in idx:
gcd_i = gcd(i, k)
result += sum(cnt for gcd_j, cnt in gcds.iteritems() if gcd_i*gcd_j%k == 0)
gcds[gcd_i] += 1
return result
# Time: O(nlogk + n * sqrt(k)^2) = O(n * k)
# Space: O(n * sqrt(k)), number of factors of k is at most sqrt(k)
import collections
# math, number theory
class Solution2(object):
def countPairs(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
def gcd(x, y):
while y:
x, y = y, x%y
return x
cnts = collections.defaultdict(collections.Counter)
for i, x in enumerate(nums):
cnts[x][gcd(i, k)] += 1
result = 0
for cnt in cnts.itervalues():
for x in cnt.iterkeys():
for y in cnt.iterkeys():
if x > y or x*y%k:
continue
result += cnt[x]*cnt[y] if x != y else cnt[x]*(cnt[x]-1)//2
return result
# Time: O(n^2)
# Space: O(n)
import collections
# brute force
class Solution3(object):
def countPairs(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
idxs = collections.defaultdict(list)
for i, x in enumerate(nums):
idxs[x].append(i)
return sum(idx[i]*idx[j]%k == 0 for idx in idxs.itervalues() for i in xrange(len(idx)) for j in xrange(i+1, len(idx)))