Open In App

Intersection of n sets

Last Updated : 23 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given n sets of integers of different sizes. Each set may contain duplicates also. How to find the intersection of all the sets. If an element is present multiple times in all the sets, it should be added that many times in the result.
For example, consider there are three sets {1,2,2,3,4} {2,2,3,5,6} {1,3,2,2,6}. The intersection of the given sets should be {2,2,3}
The following is an efficient approach to solve this problem.
1. Sort all the sets. 
2. Take the smallest set, and insert all the elements, and their frequencies into a map. 
3. For each element in the map do the following 
…..a. If the element is not present in any set, ignore it 
…..b. Find the frequency of the element in each set (using binary search). If it less than the frequency in the map, update the frequency 
…..c. If the element is found in all the sets, add it to the result.
Here is the C++ implementation of the above approach.
 

CPP




// C++ program to find intersection of n sets
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
 
// The main function that receives a set of sets as parameter and
// returns a set containing intersection of all sets
vector <int> getIntersection(vector < vector <int> > &sets)
{
    vector <int> result; // To store the resultant set
    int smallSetInd = 0; // Initialize index of smallest set
    int minSize = sets[0].size(); // Initialize size of smallest set
 
    // sort all the sets, and also find the smallest set
    for (int i = 1 ; i < sets.size() ; i++)
    {
        // sort this set
        sort(sets[i].begin(), sets[i].end());
 
        // update minSize, if needed
        if (minSize > sets[i].size())
        {
            minSize = sets[i].size();
            smallSetInd = i;
        }
    }
 
    map<int,int> elementsMap;
 
    // Add all the elements of smallest set to a map, if already present,
    // update the frequency
    for (int i = 0; i < sets[smallSetInd].size(); i++)
    {
        if (elementsMap.find( sets[smallSetInd][i] ) == elementsMap.end())
            elementsMap[ sets[smallSetInd][i] ] = 1;
        else
            elementsMap[ sets[smallSetInd][i] ]++;
    }
 
    // iterate through the map elements to see if they are present in
    // remaining sets
    map<int,int>::iterator it;
    for (it = elementsMap.begin(); it != elementsMap.end(); ++it)
    {
        int elem = it->first;
        int freq = it->second;
 
        bool bFound = true;
 
        // Iterate through all sets
        for (int j = 0 ; j < sets.size() ; j++)
        {
            // If this set is not the smallest set, then do binary search in it
            if (j != smallSetInd)
            {
                // If the element is found in this set, then find its frequency
                if (binary_search( sets[j].begin(), sets[j].end(), elem ))
                {
                int lInd = lower_bound(sets[j].begin(), sets[j].end(), elem)
                                                            - sets[j].begin();
                int rInd = upper_bound(sets[j].begin(), sets[j].end(), elem)
                                                            - sets[j].begin();
 
                // Update the minimum frequency, if needed
                if ((rInd - lInd) < freq)
                    freq = rInd - lInd;
                }
                // If the element is not present in any set, then no need
                // to proceed for this element.
                else
                {
                    bFound = false;
                    break;
                }
            }
        }
 
        // If element was found in all sets, then add it to result 'freq' times
        if (bFound)
        {
            for (int k = 0; k < freq; k++)
                result.push_back(elem);
        }
    }
    return result;
}
 
// A utility function to print a set of elements
void printset(vector <int> set)
{
    for (int i = 0 ; i < set.size() ; i++)
        cout<<set[i]<<" ";
}
 
 
// Test case
void TestCase1()
{
    vector < vector <int> > sets;
    vector <int> set1;
    set1.push_back(1);
    set1.push_back(1);
    set1.push_back(2);
    set1.push_back(2);
    set1.push_back(5);
 
    sets.push_back(set1);
 
    vector <int> set2;
    set2.push_back(1);
    set2.push_back(1);
    set2.push_back(4);
    set2.push_back(3);
    set2.push_back(5);
    set2.push_back(9);
 
    sets.push_back(set2);
 
    vector <int> set3;
    set3.push_back(1);
    set3.push_back(1);
    set3.push_back(2);
    set3.push_back(3);
    set3.push_back(5);
    set3.push_back(6);
 
    sets.push_back(set3);
 
    vector <int> r = getIntersection(sets);
 
    printset(r);
 
}
 
// Driver program to test above functions
int main()
{
    TestCase1();
    return 0;
}


Java




// Java program to find intersection of n sets
import java.util.*;
 
public class Main {
    public static List<Integer> getIntersection(List<List<Integer>> sets) {
        List<Integer> result = new ArrayList<>(); // To store the resultant set
        int smallSetInd = 0; // Initialize index of smallest set
        int minSize = sets.get(0).size(); // Initialize size of smallest set
 
        // sort all the sets, and also find the smallest set
        for (int i = 1; i < sets.size(); i++) {
            // sort this set
            Collections.sort(sets.get(i));
 
            // update minSize, if needed
            if (minSize > sets.get(i).size()) {
                minSize = sets.get(i).size();
                smallSetInd = i;
            }
        }
 
        Map<Integer, Integer> elementsMap = new HashMap<>();
 
        // Add all the elements of smallest set to a map, if already present,
        // update the frequency
        for (int i = 0; i < sets.get(smallSetInd).size(); i++) {
            int elem = sets.get(smallSetInd).get(i);
            if (!elementsMap.containsKey(elem)) {
                elementsMap.put(elem, 1);
            } else {
                elementsMap.put(elem, elementsMap.get(elem) + 1);
            }
        }
 
        // iterate through the map elements to see if they are present in
        // remaining sets
        for (Map.Entry<Integer, Integer> entry : elementsMap.entrySet()) {
            int elem = entry.getKey();
            int freq = entry.getValue();
            boolean bFound = true;
 
            // Iterate through all sets
            for (int j = 0; j < sets.size(); j++) {
                // If this set is not the smallest set, then do binary search in it
                if (j != smallSetInd) {
                    // If the element is found in this set, then find its frequency
                    if (sets.get(j).contains(elem)) {
                        int lInd = sets.get(j).indexOf(elem);
                        int rInd = sets.get(j).lastIndexOf(elem) + 1;
 
                        // Update the minimum frequency, if needed
                        if ((rInd - lInd) < freq) {
                            freq = rInd - lInd;
                        }
                    // If the element is not present in any set, then no need
                    // to proceed for this element.
                    } else {
                        bFound = false;
                        break;
                    }
                }
            }
 
            // If element was found in all sets, then add it to result 'freq' times
            if (bFound) {
                for (int i = 0; i < freq; i++) {
                    result.add(elem);
                }
            }
        }
 
        return result;
    }
 
    // A utility function to print a set of elements
    public static void printSet(List<Integer> s) {
        System.out.println(String.join(" ", s.stream().map(Object::toString).toArray(String[]::new)));
    }
 
 
    // Test case
    public static void testCase1() {
        List<List<Integer>> sets = new ArrayList<>();
        sets.add(Arrays.asList(1, 1, 2, 2, 5));
        sets.add(Arrays.asList(1, 1, 4, 3, 5, 9));
        sets.add(Arrays.asList(1, 1, 2, 3, 5, 6));
 
        List<Integer> r = getIntersection(sets);
 
        printSet(r);
    }
 
    // Driver program to test above functions
    public static void main(String[] args) {
        testCase1();
    }
}
 
// Contributed by adityasha4x71


Python3




from typing import List
 
# The main function that receives a set of sets as parameter and
# returns a set containing intersection of all sets
def get_intersection(sets: List[List[int]]) -> List[int]:
    result = []  # To store the resultant set
    small_set_ind = 0  # Initialize index of smallest set
    min_size = len(sets[0])  # Initialize size of smallest set
 
    # sort all the sets, and also find the smallest set
    for i in range(1, len(sets)):
        # sort this set
        sets[i].sort()
 
        # update minSize, if needed
        if min_size > len(sets[i]):
            min_size = len(sets[i])
            small_set_ind = i
 
    elements_map = {}
 
    # Add all the elements of smallest set to a map, if already present,
    # update the frequency
    for i in range(len(sets[small_set_ind])):
        if sets[small_set_ind][i] not in elements_map:
            elements_map[sets[small_set_ind][i]] = 1
        else:
            elements_map[sets[small_set_ind][i]] += 1
 
    # iterate through the map elements to see if they are present in
    # remaining sets
    for elem, freq in elements_map.items():
        b_found = True
 
        # Iterate through all sets
        for j in range(len(sets)):
            # If this set is not the smallest set, then do binary search in it
            if j != small_set_ind:
                # If the element is found in this set, then find its frequency
                if elem in sets[j]:
                    l_ind = sets[j].index(elem)
                    r_ind = len(sets[j]) - sets[j][::-1].index(elem)
 
                    # Update the minimum frequency, if needed
                    if (r_ind - l_ind) < freq:
                        freq = r_ind - l_ind
                # If the element is not present in any set, then no need
                # to proceed for this element.
                else:
                    b_found = False
                    break
 
        # If element was found in all sets, then add it to result 'freq' times
        if b_found:
            result += [elem] * freq
 
    return result
 
 
# A utility function to print a set of elements
def print_set(s: List[int]):
    for i in range(len(s)):
        print(s[i], end=" ")
    print()
 
 
# Test case
def test_case_1():
    sets = [[1, 1, 2, 2, 5],
            [1, 1, 4, 3, 5, 9],
            [1, 1, 2, 3, 5, 6]]
 
    r = get_intersection(sets)
 
    print_set(r)
 
 
# Driver program to test above functions
def main():
    test_case_1()
    return 0
 
if __name__ == "__main__":
    main()


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    // The main function that receives a set of sets as
    // parameter and returns a set containing intersection
    // of all sets
    static List<int> GetIntersection(List<List<int> > sets)
    {
        List<int> result
            = new List<int>(); // To store the resultant set
        int smallSetInd
            = 0; // Initialize index of smallest set
        int minSize
            = sets[0]
                  .Count; // Initialize size of smallest set
 
        // sort all the sets, and also find the smallest set
        for (int i = 1; i < sets.Count; i++) {
            // sort this set
            sets[i].Sort();
 
            // update minSize, if needed
            if (minSize > sets[i].Count) {
                minSize = sets[i].Count;
                smallSetInd = i;
            }
        }
 
        Dictionary<int, int> elementsMap
            = new Dictionary<int, int>();
 
        // Add all the elements of smallest set to a map, if
        // already present, update the frequency
        for (int i = 0; i < sets[smallSetInd].Count; i++) {
            int elem = sets[smallSetInd][i];
            if (!elementsMap.ContainsKey(elem))
                elementsMap[elem] = 1;
            else
                elementsMap[elem]++;
        }
 
        // iterate through the map elements to see if they
        // are present in remaining sets
        foreach(KeyValuePair<int, int> kvp in elementsMap)
        {
            int elem = kvp.Key;
            int freq = kvp.Value;
 
            bool bFound = true;
 
            // Iterate through all sets
            for (int j = 0; j < sets.Count; j++) {
                // If this set is not the smallest set, then
                // do binary search in it
                if (j != smallSetInd) {
                    // If the element is found in this set,
                    // then find its frequency
                    if (sets[j].BinarySearch(elem) >= 0) {
                        int lInd = sets[j].IndexOf(elem);
                        int rInd
                            = sets[j].LastIndexOf(elem);
 
                        // Update the minimum frequency, if
                        // needed
                        if ((rInd - lInd + 1) < freq)
                            freq = rInd - lInd + 1;
                    }
                    // If the element is not present in any
                    // set, then no need to proceed for this
                    // element.
                    else {
                        bFound = false;
                        break;
                    }
                }
            }
 
            // If element was found in all sets, then add it
            // to result 'freq' times
            if (bFound) {
                for (int k = 0; k < freq; k++)
                    result.Add(elem);
            }
        }
 
        return result;
    }
 
    // A utility function to print a set of elements
    static void PrintSet(List<int> set)
    {
        foreach(int i in set) Console.Write(i + " ");
        Console.WriteLine();
    }
 
    // Test case
    static void TestCase1()
    {
        List<List<int> > sets = new List<List<int> >();
        List<int> set1 = new List<int>{ 1, 1, 2, 2, 5 };
        sets.Add(set1);
 
        List<int> set2 = new List<int>{ 1, 1, 4, 3, 5, 9 };
        sets.Add(set2);
        List<int> set3 = new List<int>{ 1, 1, 2, 3, 5, 6 };
        sets.Add(set3);
        List<int> r = GetIntersection(sets);
        PrintSet(r);
    }
    // Driver program to test above functions
    public static void Main() { TestCase1(); }
}


Javascript




function getIntersection(sets) {
  let result = []; // To store the resultant set
  let smallSetInd = 0; // Initialize index of smallest set
  let minSize = sets[0].length; // Initialize size of smallest set
 
  // sort all the sets, and also find the smallest set
  for (let i = 1; i < sets.length; i++) {
    // sort this set
    sets[i].sort((a, b) => a - b);
 
    // update minSize, if needed
    if (minSize > sets[i].length) {
      minSize = sets[i].length;
      smallSetInd = i;
    }
  }
 
  let elementsMap = new Map();
 
  // Add all the elements of smallest set to a map, if already present,
  // update the frequency
  for (let i = 0; i < sets[smallSetInd].length; i++) {
    let elem = sets[smallSetInd][i];
    if (!elementsMap.has(elem)) {
      elementsMap.set(elem, 1);
    } else {
      elementsMap.set(elem, elementsMap.get(elem) + 1);
    }
  }
 
  // iterate through the map elements to see if they are present in
  // remaining sets
  for (let [elem, freq] of elementsMap) {
    let bFound = true;
 
    // Iterate through all sets
    for (let j = 0; j < sets.length; j++) {
      // If this set is not the smallest set, then do binary search in it
      if (j !== smallSetInd) {
        // If the element is found in this set, then find its frequency
        if (sets[j].includes(elem)) {
          let lInd = sets[j].indexOf(elem);
          let rInd = sets[j].lastIndexOf(elem) + 1;
 
          // Update the minimum frequency, if needed
          if ((rInd - lInd) < freq) {
            freq = rInd - lInd;
          }
        // If the element is not present in any set, then no need
        // to proceed for this element.
        } else {
          bFound = false;
          break;
        }
      }
    }
 
    // If element was found in all sets, then add it to result 'freq' times
    if (bFound) {
      for (let i = 0; i < freq; i++) {
        result.push(elem);
      }
    }
  }
 
  return result;
}
 
// A utility function to print a set of elements
function printSet(s) {
  console.log(s.join(" "));
}
 
// Test case
function testCase1() {
  let sets = [    [1, 1, 2, 2, 5],
    [1, 1, 4, 3, 5, 9],
    [1, 1, 2, 3, 5, 6]
  ];
 
  let r = getIntersection(sets);
 
  printSet(r);
}
 
// Driver program to test above functions
testCase1();


Output: 

1 1 5

Time Complexity: Let there be ‘n’ lists, and the average size of lists be ‘m’. Sorting phase takes O( n* m *log m) time (Sorting n lists with average length m). Searching phase takes O( m * n * log m) time. ( for each element in a list, we are searching n lists with log m time). So the overall time complexity is O( n*m*log m ).
Auxiliary Space: O(m) space for storing the map.
This article is compiled by Ravi Chandra Enaganti.
 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads