Given two unsorted arrays that represent two sets (elements in every array are distinct), find union and intersection of two arrays.
For example, if the input arrays are:
arr1[] = {7, 1, 5, 2, 3, 6}
arr2[] = {3, 8, 6, 20, 7}
Then your program should print Union as {1, 2, 3, 5, 6, 7, 8, 20} and Intersection as {3, 6}. Note that the elements of union and intersection can be printed in any order.
Method 1 (Naive)
Union:
1) Initialize union U as empty.
2) Copy all elements of first array to U.
3) Do following for every element x of second array:
…..a) If x is not present in first array, then copy x to U.
4) Return U.
Intersection:
1) Initialize intersection I as empty.
2) Do following for every element x of first array
…..a) If x is present in second array, then copy x to I.
4) Return I.
Time complexity of this method is O(mn) for both operations. Here m and n are number of elements in arr1[] and arr2[] respectively.
Method 2 (Use Sorting)
1) Sort arr1[] and arr2[]. This step takes O(mLogm + nLogn) time.
2) Use O(m + n) algorithms to find union and intersection of two sorted arrays.
Overall time complexity of this method is O(mLogm + nLogn).
Method 3 (Use Sorting and Searching)
Union:
1) Initialize union U as empty.
2) Find smaller of m and n and sort the smaller array.
3) Copy the smaller array to U.
4) For every element x of larger array, do following
…….b) Binary Search x in smaller array. If x is not present, then copy it to U.
5) Return U.
Intersection:
1) Initialize intersection I as empty.
2) Find smaller of m and n and sort the smaller array.
3) For every element x of larger array, do following
…….b) Binary Search x in smaller array. If x is present, then copy it to I.
4) Return I.
Time complexity of this method is min(mLogm + nLogm, mLogn + nLogn) which can also be written as O((m+n)Logm, (m+n)Logn). This approach works much better than the previous approach when difference between sizes of two arrays is significant.
public class IntersectUnionArray { private int binarySearch(int[] A, int target) { int start = 0, end = A.length-1; while(start <= end) { int m = (start+end)/2; if(A[m] == target) { return m; } else if(A[m] < target) { start = m+1; } else { end = m-1; } } return -1; } public List<Integer> unionArray(int[] A, int[] B) { if(A.length > B.length) { return unionArray(B, A); } Arrays.sort(A); List<Integer> list = new ArrayList<>(); for(int num:A) { list.add(num); } for(int num:B) { if(binarySearch(A, num) == -1) { list.add(num); } } return list; } public List<Integer> intersectArray(int[] A, int[] B) { if(A.length > B.length) { return intersectArray(B, A); } Arrays.sort(A); List<Integer> list = new ArrayList<>(); for(int num:B) { if(binarySearch(A, num) != -1) { list.add(num); } } return list; } public static void main(String[] args) { int[] A = {7, 1, 5, 2, 3, 6}; int[] B = {3, 8, 6, 20, 7}; IntersectUnionArray iu = new IntersectUnionArray(); System.out.println(iu.unionArray(A, B)); System.out.println(iu.intersectArray(A, B)); } }
Method 4 (Use Hashing)
Union:
1) Initialize union U as empty.
1) Initialize an empty hash table.
2) Iterate through first array and put every element of first array in the hash table, and in U.
4) For every element x of second array, do following
…….a) Search x in the hash table. If x is not present, then copy it to U.
5) Return U.
Intersection:
1) Initialize intersection I as empty.
2) In initialize an empty hash table.
3) Iterate through first array and put every element of first array in the hash table.
4) For every element x of second array, do following
…….a) Search x in the hash table. If x is present, then copy it to I.
5) Return I.
Time complexity of this method is Θ(m+n) under the assumption that hash table search and insert operations take Θ(1) time.
Reference:
http://www.geeksforgeeks.org/find-union-and-intersection-of-two-unsorted-arrays/