Skip to content

Commit 0058110

Browse files
authored
Create count-pairs-of-nodes.py
1 parent 8f9c442 commit 0058110

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

Python/count-pairs-of-nodes.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Time: O(n + e + q)
2+
# Space: O(n + e)
3+
4+
import collections
5+
import itertools
6+
7+
8+
# pure counting solution
9+
class Solution(object):
10+
def countPairs(self, n, edges, queries):
11+
"""
12+
:type n: int
13+
:type edges: List[List[int]]
14+
:type queries: List[int]
15+
:rtype: List[int]
16+
"""
17+
degree = [0]*(n+1)
18+
shared = collections.Counter((min(n1, n2), max(n1, n2)) for n1, n2 in edges)
19+
for u, v in edges:
20+
degree[u] += 1
21+
degree[v] += 1
22+
cnt = [0]*(2*(max(degree[1:])+1))
23+
count = collections.Counter(degree[1:])
24+
for i, j in itertools.product(count, count): # Time: O(d^2) = O(e)
25+
if i < j:
26+
cnt[i+j] += count[i]*count[j]
27+
elif i == j:
28+
cnt[i+j] += count[i]*(count[i]-1)//2
29+
for (i, j), shared_degree in shared.iteritems():
30+
cnt[degree[i]+degree[j]] -= 1
31+
cnt[degree[i]+degree[j]-shared_degree] += 1
32+
for i in reversed(xrange(len(cnt)-1)): # accumulate
33+
cnt[i] += cnt[i+1]
34+
return [cnt[q+1] if q+1 < len(cnt) else 0 for q in queries]
35+
36+
37+
# Time: O(nlogn + q * (n + e))
38+
# Space: O(n + e)
39+
import collections
40+
41+
42+
# two pointers solution
43+
class Solution2(object):
44+
def countPairs(self, n, edges, queries):
45+
"""
46+
:type n: int
47+
:type edges: List[List[int]]
48+
:type queries: List[int]
49+
:rtype: List[int]
50+
"""
51+
degree = [0]*(n+1)
52+
shared = collections.Counter((min(n1, n2), max(n1, n2)) for n1, n2 in edges)
53+
for n1, n2 in edges:
54+
degree[n1] += 1
55+
degree[n2] += 1
56+
sorted_degree = sorted(degree)
57+
result = []
58+
for k, q in enumerate(queries):
59+
left, right = 1, n
60+
cnt = 0
61+
while left < right:
62+
if q < sorted_degree[left]+sorted_degree[right]:
63+
cnt += right-left
64+
right -= 1
65+
else:
66+
left += 1
67+
for (i, j), shared_degree in shared.iteritems():
68+
if degree[i]+degree[j]-shared_degree <= q < degree[i]+degree[j]:
69+
cnt -= 1
70+
result.append(cnt)
71+
return result

0 commit comments

Comments
 (0)