Introduction to Operating std::unordered_set in C++

Welcome back! Today, we're diving into C++'s std::unordered_set — a key player in efficient collection manipulation. Much like a mathematical set, std::unordered_set guarantees uniqueness by disallowing duplicates, akin to assigning unique membership IDs in a club. Throughout this session, you'll discover how std::unordered_set simplifies the problems of ensuring uniqueness and checking for overlaps. Let's see how it transforms long, cumbersome operations into efficient, elegant code.

Problem 1: Check if Two Sets are Disjoint

Imagine you're developing a feature for a social media platform that requires user groups to be exclusive — you need to ensure users can't belong to more than one group at a time. It's like organizing events where a guest shouldn't appear on the lists for two different parties — an overlap would be a significant issue.

Naive Approach

Initially, you might consider checking for overlap by comparing each member of one group with every member of the other — a somewhat cumbersome O(n * m) operation. If you have hundreds or thousands of users in each group, the time it takes to compare them all grows exponentially. This approach is impractical and resource-intensive, especially on a social media platform scale with potentially millions of users.

bool AreDisjoint(const std::vector<int>& arr1, const std::vector<int>& arr2) {
    for (int num1 : arr1) {
        for (int num2 : arr2) {
            if (num1 == num2) {
                return false; // An overlap is found.
            }
        }
    }
    return true; // No overlaps found, sets are disjoint.
}
Efficient Approach

Instead, std::unordered_set offers a fast and efficient method for achieving the same result. Let's walk through the implementation:

#include <unordered_set>
#include <vector>

bool AreDisjoint(const std::vector<int>& arr1, const std::vector<int>& arr2) {
    std::unordered_set<int> set1(arr1.begin(), arr1.end()); // Populate unordered_set

    for (int num : arr2) {
        if (set1.find(num) != set1.end()) {
            return false; // If found, the sets are not disjoint.
        }
    }
    return true; // No overlaps found, sets are disjoint.
}

std::unordered_set provides significant speed advantages due to its hash table structure, offering average constant time, O(1), for operations like insert() and find(). This efficiency comes from computing hash codes for swift access and retrieval, unlike lists or arrays that offer linear time complexity, O(n), for similar operations. This ultimately results in a function with a time complexity of O(n). It inherently manages duplicates by allowing each element to be added only once, simplifying the logic for uniqueness checks. These features make std::unordered_set an ideal choice for tasks requiring quick membership checks and ensuring unique elements.

Note: Here, we use the range constructor of std::unordered_set to initialize the set directly from arr1. This constructor takes two iterators (the beginning and end of the array) and adds each element to the set, ensuring only unique elements are stored. This conversion takes linear time, O(n), for arr1.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal