Problem overview
The method GuestsMissing gets two lists of names, invited and arrived. It returns how many invited guests haven't arrived yet.
Two details matter. A guest may check in more than once, and still counts as one guest. And someone who wasn't invited may check in too, which doesn't change the answer.
With invited = ["Ava", "Leo", "Mia", "Zoe"] and arrived = ["Leo", "Zoe"], Ava and Mia are still missing, so the answer is 2. With invited = ["Ava", "Leo"] and arrived = ["Leo", "Max", "Leo"], Leo checked in twice but is one guest, and Max wasn't invited, so only Ava is missing: the answer is 1. If nobody has arrived, everyone invited is missing.
Approach
Start by assuming that every invited guest is missing. Then go through the arrivals and cross each name off. Whatever is left at the end is the answer.
A HashSet fits this well. It holds each name once, and its Remove method quietly does nothing when the name isn't in the set. That one behaviour handles both tricky cases: a guest who checks in twice is crossed off the first time and the second Remove finds nothing, and an uninvited guest was never in the set to begin with.
Step by step
- Build the set of missing guests from
invited:new HashSet<string>(invited). - Loop over
arrivedwithforeach, using astringnamedname. - Remove each name from
missing. Noifis needed: a repeat or an uninvited name is simply ignored. - Return
missing.Countafter the loop.
The solution in C#
class Solution {
public int GuestsMissing(List<string> invited, List<string> arrived) {
HashSet<string> missing = new HashSet<string>(invited);
foreach (string name in arrived) {
missing.Remove(name);
}
return missing.Count;
}
}
The details worth knowing:
Removereturns abool(trueif it removed something). This solution ignores it, which is allowed in C#.- The size of a set is
Count, notLength. - The method doesn't change the
invitedlist: the set is a separate copy.
Tracing the second example
The set missing starts as Ava and Leo. The arrivals are then handled one by one:
| name | Remove returns | names left |
|---|---|---|
| Leo | true | 1 |
| Max | false | 1 |
| Leo | false | 1 |
Max was never invited and the second Leo is already gone, so neither changes the set. One name, Ava, is left.
Testing
Run on the statement's three examples, the method returns:
2
1
2
The third example passes an empty arrived list, so the loop never runs and the set keeps both names.
Edge cases and common mistakes
- Subtracting list sizes.
invited.Count - arrived.Countgives -1 for the second example, because it counts the repeated check-in and the uninvited guest. Only the set removal handles those cases. - Counting arrivals that are invited. That also works if you remember to count each guest once, but it needs extra care for repeats; crossing names off a set doesn't.
- Checking
ContainsbeforeRemove. It's harmless but unnecessary, becauseRemoveof a missing value does nothing. - Using a list for
missing.List.Removealso returnsfalsefor a missing value, but it removes only one copy and checks values one by one, so a set is the better fit.
