Mutual Follow Pairs
Problem
A social app stores who follows whom as a list of pairs [a, b], meaning person a follows person b, with people numbered 0 to n - 1. The list may contain the same pair more than once, and nobody follows themselves. Return how many unordered pairs of people follow each other.
Examples
Input: n = 4, follows = [[0, 1], [1, 0], [1, 2], [2, 3], [3, 2], [0, 2]]
Output: 2
Why: 0 and 1, and 2 and 3; 1 follows 2 but not the other way round
Input: n = 3, follows = [[0, 1], [0, 1], [1, 0]]
Output: 1
Why: the repeated pair still describes one mutual pair
Input: n = 2, follows = []
Output: 0
Why: edge case, nobody follows anyone
Hints
0 / 3
For every follow from a to b, the question is whether the reverse follow from b to a exists. How quickly can a graph representation answer that?
An adjacency matrix answers it in constant time but needs n squared memory. A set of neighbours per person also answers it in constant time on average and only stores the follows that exist.
Build a set of followed people for each person, which also drops repeated pairs. Then for each person a and each b in a's set, count the pair when a is less than b and a appears in b's set.
Solution
Storing each person's follows as a set gives an adjacency list that doubles as a fast edge test, which is the one question this problem keeps asking. The sets also absorb repeated pairs, so a duplicate can never be counted twice. Every mutual pair is seen twice, once from each side, and the a < b test keeps exactly one of those sightings. Time is O(n + m) on average for m follow pairs, and space is O(n + m).
def mutual_pairs(n, follows):
adj = [set() for _ in range(n)] # adjacency sets: fast edge tests
for a, b in follows:
adj[a].add(b)
count = 0
for a in range(n):
for b in adj[a]:
if a < b and a in adj[b]: # a < b counts each pair once
count += 1
return count
print(mutual_pairs(4, [[0, 1], [1, 0], [1, 2], [2, 3], [3, 2], [0, 2]])) # -> 2
print(mutual_pairs(3, [[0, 1], [0, 1], [1, 0]])) # -> 1
print(mutual_pairs(2, [])) # -> 0Stuck on the idea rather than the code? List vs Matrix covers it.