Solution: Intersection
The intersection keeps only the elements that are in both sets. As in the union, is the size of and is the size of . The array arr1 holds and arr2 holds .
On an unsorted set
Iterate over and keep each element that also appears in :
public static int[] intersection(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length];
int k = 0;
for (int i = 0; i < arr1.length; i++) {
if (contains(arr2, arr1[i])) {
result[k++] = arr1[i];
}
}
return trim(result, k);
}
The contains and trim helpers are the same ones the union uses. The intersection cannot have more values than has, so result is allocated at length .
This loop has the same structure and the same cost as the second loop of the union. It does one linear scan for each element. Here that is linear scans of , so the cost is . You can improve this a little by iterating over whichever set is smaller and testing each element against the larger set. It does not change the Big-Oh.
On a sorted set
The merge works here with one change. It copies an element only when the elements at the two pointers are equal.
public static int[] sortedIntersection(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length];
int i = 0, j = 0, k = 0;
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
i++; // in arr1 only: skip
} else if (arr1[i] > arr2[j]) {
j++; // in arr2 only: skip
} else {
result[k++] = arr1[i++]; // a tie: in both, copy the value once
j++;
}
}
return trim(result, k);
}
When the two elements differ, the smaller element is in just one of the sets and cannot be in the intersection, so we skip it. The loop stops as soon as one pointer reaches the end of its array, and there is no copy-the-remainder step, because the elements left in the other array are in only one set. The merge is still , and the result is sorted.
| Implementation | Intersection cost |
|---|---|
LinkedSet/ArraySet |
|
SortedArraySet |