Dynamic Programming · 9 of 60
Friends Pairing Problem
Count the ways a group of friends can go to a dance, where each friend goes alone or with exactly one partner.
- Simple way
- time O(2^n)
room O(n) - Clever way
- time O(n)
room O(1)
The problem, simply
There are n friends. Each friend either stays single or pairs up with exactly one other friend. A friend can be in at most one pair. Count all the different ways this can happen.
Pairs have no order: A with B is the same pair as B with A. The answer grows fast, so judges want it modulo 10^9 + 7.
A story to remember it
Picture it
Four friends are dots. Every line is a pair that could dance together. One arrangement picks a few lines that do not share a dot: here A dances with C, and B and D dance alone. Count every such choice of lines (including no lines at all).
- done
- answer
- ignored
Examples
Three friends
- In
n = 3- Out
4
All alone; A with B and C alone; A with C and B alone; B with C and A alone.
Four friends
- In
n = 4- Out
10
1 way all alone, 6 ways with one pair, and 3 ways with two pairs. f(3) + 3 x f(2) = 4 + 6 = 10.
One friend
- In
n = 1- Out
1
Alone is the only option.
Two friends
- In
n = 2- Out
2
Both alone, or together.
Six friends
- In
n = 6- Out
76
f(5) + 5 x f(4) = 26 + 50 = 76.
Way 1: the simple way
Write the story as recursion. Look at the last friend.
f(1) = 1andf(2) = 2.- Last friend alone:
f(n - 1)ways for the rest. - Last friend in a pair:
n - 1partner choices, thenf(n - 2)ways for the rest. - Add them.
f(5) asks f(4) (the last friend stays alone) and f(3) (the last friend picks one of 4 partners, so times 4). f(3) and f(2) get asked again and again (faded). Double rings are the small cases: f(1) = 1 and f(2) = 2.
- seen
class Solution {
public long countFriendsPairings(int n) {
if (n <= 2) return n; // f(1) = 1, f(2) = 2
long alone = countFriendsPairings(n - 1); // last friend stays single
long paired = (n - 1) * countFriendsPairings(n - 2); // picks one of n-1 partners
return alone + paired;
}
}How long it takes: two calls each time, like Fibonacci, so up to O(2^n) calls. Extra room: the chain of calls, O(n).
Way 2: the clever way
Every f(i) only needs f(i - 1) and f(i - 2). Compute them from small to big and keep just the last two.
prev2 = f(1) = 1,prev1 = f(2) = 2.- For
ifrom 3 ton:cur = prev1 + (i - 1) * prev2, then slide. - Return
prev1.
Add one friend at a time
01 / 07
Box i holds f(i), the number of arrangements for i friends. One friend can only dance alone: f(1) = 1.
- looking now
- checking
- answer
- just added
class Solution {
public long countFriendsPairings(int n) {
final long MOD = 1_000_000_007L;
if (n <= 2) return n;
long prev2 = 1; // f(1)
long prev1 = 2; // f(2)
for (int i = 3; i <= n; i++) {
// alone: f(i-1); with a partner: (i-1) choices times f(i-2)
long cur = (prev1 + (long) (i - 1) * prev2) % MOD;
prev2 = prev1;
prev1 = cur;
}
return prev1;
}
}How long it takes: one step per friend, O(n). Extra room: two numbers, O(1).
Watch out for
- Overflow. f(20) is already over 23 billion, which does not fit in an
int. Uselongand the modulo. - Multiply
(i - 1) * prev2aslongbefore taking the modulo. f(0)is 1 if the judge asks for it (nobody, one way).
What interviewers ask next
- Groups of up to three? The newest friend is alone, picks 1 partner, or picks 2:
f(n) = f(n-1) + (n-1) f(n-2) + C(n-1, 2) f(n-3). - Everyone must be in a pair (no singles)? For even
nthe answer is(n-1) x (n-3) x ... x 1. The newest picks a partner, and nobody may stay alone. - Where else does this sequence show up? It counts shuffles that undo themselves when done twice (involutions), and phone lines where each line connects at most two people. Quant interviews sometimes ask it in that form.
- Print all arrangements? Backtracking: for the first free friend, try alone, then try each later free friend as a partner.
Remember this
Grown-up words: a set of pairs that share nobody is a matching in a complete graph, the count is the telephone numbers or involution numbers, the faded repeats are overlapping subproblems, and keeping two numbers is space optimization.