Problem overview
The method countHandShakes receives n, the number of friends in a group. Everybody shakes hands with everybody else exactly once, and the method 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 there are six: (A, B), (A, C), (A, D), (B, C), (B, D) and (C, D).
Approach
One way is to count by hand: A shakes with the 3 others, B then adds 2 new ones, C adds 1, and D adds none. The total is 3 + 2 + 1 = 6. In general the sum is (n - 1) + (n - 2) + ... + 1. A loop could add it up, but a formula is shorter and faster.
There is a quicker way to see the formula. Each of the n people shakes hands with the other n - 1 people, which makes n * (n - 1). But that counts every handshake twice, once from each side: A's handshake with B is also B's handshake with A. Dividing by 2 fixes this:
handshakes = n * (n - 1) / 2
For n = 4 that is 4 * 3 / 2 = 6, which matches the list.
Step by step
- Count the ordered pairs. Multiply
nbyn - 1. Wrapn - 1in parentheses so the subtraction happens first. - Remove the double counting. Divide the product by 2.
- Return the result. The method returns an
Int, which is what the division of two integers gives.
The solution in Swift
class Solution {
func countHandShakes(_ n: Int) -> Int {
return (n * (n - 1)) / 2
}
}
Swift details worth knowing:
- The division is exact. Of any two consecutive numbers, one is even, so
n * (n - 1)is always even. Integer division, which drops fractions, therefore loses nothing here. - Multiply before dividing. Doing the multiplication first keeps every step a whole number. Swift evaluates
*and/from left to right anyway. - Overflow crashes.
Intis 64 bits, and arithmetic that overflows stops the program at run time. The productn * (n - 1)only gets that large oncenpasses about 3.04 billion, far beyond what a group of friends needs.
Another way to see the formula
Write the handshakes of the friend who joins last. When person number k arrives, they shake hands with the k - 1 people already there. So the total for n people is 0 + 1 + 2 + ... + (n - 1). Pairing the first term with the last, the second with the second to last, and so on, gives pairs that each add up to n - 1. There are n / 2 such pairs, which leads to the same n * (n - 1) / 2.
Complexity
Time and space are both O(1): the method does one subtraction, one multiplication and one division, whatever the value of n. A loop that adds 1 + 2 + ... + (n - 1) would take O(n) time.
Edge cases and common mistakes
- One person or nobody. For
n = 1the formula gives1 * 0 / 2 = 0, and forn = 0it also gives0. No pair, no handshake. - Two people.
2 * 1 / 2 = 1: a single handshake. - Forgetting to halve.
n * (n - 1)counts each handshake twice. - Using
n * n / 2. That includes people shaking their own hands. - Missing parentheses around
n - 1.n * n - 1is a different number.
Testing
n = 3gives3.n = 4gives6.n = 1gives0.n = 10gives45.
