Problem overview
There are n friends, and everyone shakes hands with everyone else exactly once. The method countHandShakes returns how many handshakes happen.
For n = 3 with friends A, B and C, the handshakes are (A, B), (A, C) and (B, C), so the answer is 3. For n = 4 the pairs are (A, B), (A, C), (A, D), (B, C), (B, D) and (C, D), which makes 6.
Approach
Counting by listing pairs works for small groups, but a formula is better. There are two ways to reach it.
Count from each person's side
Each of the n people shakes hands with the other n - 1 people. That gives n * (n - 1). But a handshake involves two people, so it was counted once from each side. Dividing by 2 fixes the double counting: n * (n - 1) / 2. For n = 4 that is 4 * 3 / 2 = 6.
Add up the pairs by first friend
A shakes hands with 3 others (B, C, D), B has 2 new ones (C, D), and C has 1 (D). The total is 3 + 2 + 1 = 6. In general the sum is (n - 1) + (n - 2) + ... + 1. Write that sum once forwards and once backwards, one above the other. Each of the n - 1 columns adds up to n, so the two rows together total n * (n - 1), and the sum itself is half of that: the same formula.
A loop that adds up the sums would run in O(n) time. The formula needs a single multiplication, subtraction and division.
Step by step
- Compute
n - 1. This is how many other people each person meets. - Multiply by
n. This counts every handshake twice. - Divide by 2. The product is always even, since either
norn - 1is even. Integer division therefore loses nothing. - Return the result.
The solution in Scala
class Solution {
def countHandShakes(n: Int): Int = {
return (n * (n - 1)) / 2
}
}
Scala details:
- The multiplication happens first. The parentheses make the order explicit. Writing
n * (n - 1) / 2would evaluate the same way, because*and/have equal precedence and group left to right. Dividingn - 1by 2 first and then multiplying would be wrong: forn = 4it would compute4 * (3 / 2) = 4. - Integer division. Both sides are
Int, so the result is anIntwith any remainder dropped. Since the product is even, there is no remainder to drop. returnis optional. The last expression is the block's value, so the line could be written without it.
Complexity
Time: O(1). A fixed number of arithmetic operations.
Space: O(1). No extra storage.
Edge cases and common mistakes
- Zero or one friend.
countHandShakes(1)is0, since the one person has nobody to meet.countHandShakes(0)is0as well. - Forgetting to halve.
n * (n - 1)counts each handshake twice. Forn = 3it gives6instead of3. - Using
n * n / 2. That counts a person shaking their own hand. Forn = 3it gives4instead of3. - Overflow. An
Intwraps silently past 2,147,483,647, and the intermediate productn * (n - 1)is twice the answer. Forn = 100000the true answer is 4,999,950,000, which doesn't fit in anInt, and the method returns704982704. With aLongparameter and result type, the same formula would stay exact for much larger groups.
Testing
n = 3gives3.n = 4gives6.n = 1gives0.n = 0gives0.
