Start learning free

LESSON 239 OF 677 · SETS

Guest Check-In in Kotlin: Removing From a HashSet

Practice Read the full explanation

You get two ArrayLists of names, invited and arrived. Return how many invited guests haven't arrived yet.

A guest may check in more than once. They still count as one guest.

Someone who wasn't invited may check in too. They don't change the answer.

 

Example 1:

Input: invited = ["Ava", "Leo", "Mia", "Zoe"], arrived = ["Leo", "Zoe"]
Output: 2
Explanation: Leo and Zoe are here.
Ava and Mia haven't arrived yet.

Example 2:

Input: invited = ["Ava", "Leo"], arrived = ["Leo", "Max", "Leo"]
Output: 1
Explanation: Leo checked in twice, but he is one guest.
Max wasn't invited.
Only Ava is missing.

Example 3:

Input: invited = ["Sam", "Kim"], arrived = []
Output: 2
Explanation: Nobody has arrived yet.

 

Constraints:

  • invited has 1 to 100 names.
  • arrived has 0 to 100 names.
  • The names in invited are all different.
  • Each name is one word of English letters, starting with a capital letter.
STEP 1 OF 4
    Ctrl + Enter to check

    KOTLIN · SETS

    Guest Check In in Kotlin, explained

    Problem overview

    The function guestsMissing gets two lists of names, invited and arrived. It returns how many invited guests have not arrived yet. Three details shape the solution:

    • A guest may check in more than once, but still counts as one guest.
    • Someone who was not invited may check in too, and that must not change the answer.
    • The names in invited are all different; arrived may be empty.

    With invited = ["Ava", "Leo", "Mia", "Zoe"] and arrived = ["Leo", "Zoe"], the answer is 2: Ava and Mia are still missing. With invited = ["Ava", "Leo"] and arrived = ["Leo", "Max", "Leo"], the answer is 1: Leo came twice, Max was not invited, and only Ava is missing.

    Approach

    Do not compare the two sizes. Subtracting the size of arrived from the size of invited gives -1 for the second example, because it counts the repeat and the uninvited guest.

    Think of the invited list as a list of people still expected. Start with everyone as missing, then cross off each arrival. A HashSet fits: removing a name that is not in the set does nothing, and removing a name twice also does nothing the second time. Both awkward cases then solve themselves, with no extra if. What is left in the set at the end is exactly the invited guests who never checked in.

    Step by step

    1. Build the set of missing guests from the invited list, with invited.toHashSet(), in a val named missing. At the start, everybody is missing.
    2. Loop over arrived, with the loop variable name.
    3. Inside the loop, call missing.remove(name). If name was invited and still in the set, it comes out. If not (an uninvited guest, or a repeat arrival), remove returns false and the set stays as it was.
    4. After the loop, return missing.size.

    The solution in Kotlin

    class Solution {
        fun guestsMissing(invited: List<String>, arrived: List<String>): Int {
            val missing = invited.toHashSet()
            for (name in arrived) {
                missing.remove(name)
            }
            return missing.size
        }
    }
    

    The call missing.remove(name) returns a Boolean, and the code ignores it, which Kotlin allows. The set is a copy: it does not change the invited list, which the caller still has. val is fine for missing, since the variable never points to another set; only the set's contents change.

    The three examples give:

    2
    1
    2
    

    In the third, arrived is empty, so the loop does nothing and both invited guests, Sam and Kim, remain.

    Complexity

    Building the set takes one step per invited name, and each remove is fast, so the work is proportional to the two lists' lengths added together. The set takes space for the invited names.

    Common mistakes

    • Subtracting sizes. It breaks on repeats and uninvited guests, as shown above.
    • Counting arrivals that are in invited. A guest who checks in twice would be counted twice, unless you also track who was counted.
    • Using lists instead of a set. A list's remove works too, but a set's one-step check is simpler to reason about and does not scan the list for each name.
    • Guarding with an if before removing. It is not needed; remove already ignores a missing name.
    Keep going with Kotlin500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free