How can I efficiently check to see whether all the elements in an integer array are subset of all elements of another Array in java? For example [33 11 23] is subset of [11 23 33 42]. Thanks in advance.
Make a HashSet
out of the superset array. Check if each of the elements of the subset array are contained in the HashSet
. This is a very fast operation.
If you're not bound to using Arrays, any Java collection has the containsAll
method:
boolean isSubset = bigList.containsAll(smallList);
This will do exactly what you want, efficiently.
assume you want to check A is subset of B. put each element of B into a hash, then iterate over elements in A, all of them must exist in the hash
I have came with two different solution
input:
int mainArray[] = { 1, 2, 3, 2, 5, 6, 2 }, subArray[] = { 2, 2, 2 };
first solution iterates over both arrays and compare,
main[i] = -1
is used to avoid repeating elements included againvoid findIfArrayIsASubset(int[] main, int[] sub) { int count = 0; for (int i = 0; i < main.length; i++) { for (int j = 0; j < sub.length; j++) { if (main[i] == sub[j]) { main[i] = -1; count++; break; } } } if (count == sub.length) System.out.println("is a subset"); else System.out.println("is not a subset"); }
second solution uses hashmap having keys from
1....9
and value as0
,
next we iterate over main array and+1
to respective value
next we iterate over sub array and-1
to respective value
next comapre sum of values of hashmap to difference in length of two arrayvoid findIfArrayIsASubset(int[] main, int[] sub) { Map<Integer, Integer> mainMap = new HashMap<Integer, Integer>(); for (int i = 0; i < 10; i++) { mainMap.put(i, 0); } for (int i = 0; i < main.length; i++) { mainMap.put(main[i], mainMap.get(main[i]) + 1); } for (int i = 0; i < sub.length; i++) { mainMap.put(main[i], mainMap.get(main[i]) - 1); } String output = mainMap.values().stream().reduce(0, Integer::sum).compareTo(main.length - sub.length) == 0 ? "is a subset" : "not a subset"; System.out.println(output); }
The outer loop picks all the elements of arr2[] one by one. The inner loop linearly searches for the element picked by outer loop. If all elements are found then return true, else return false.
boolean checkIsSubset(int arr1[], int arr2[]){
int m=arr1.length, n=arr2.length;
int i = 0;
int j = 0;
for (i=0; i<n; i++){
for (j = 0; j<m; j++){
if(arr2[i] == arr1[j])
break;
}
if (j == m)
return false;
}
return true;
}
Why do binary search after sorting?? Since both arrays will be available in sorted form, we can just use two pointers as follows:-
boolean isSubset(int arr1[], int arr2[], int m, int n){
int i = 0, j = 0;
quickSort(arr1, 0, m-1);
quickSort(arr2, 0, n-1);
while( i < n && j < m )
{
if( arr1[j] <arr2[i] )
j++;
else if( arr1[j] == arr2[i] )
{
j++;
i++;
}
else if( arr1[j] > arr2[i] )
return false;
}
if( i < n )
return false;
else
return true;
}
Sort both the arrays and check all the elements in smaller array are present in larget array. This is without using extra space.
If not use hasmap as someone already suggested.
This checks if any elements of the possible subset is missing from the larger array. If it is, it's not a subset:
boolean isSubset(int[] a1, int[] a2) {
a2 = Arrays.copyOf(a2, a2.length);
Arrays.sort(a2);
for(int e : a1) {
if (Arrays.binarySearch(a2, e) < 0) {
return false;
}
}
return true;
}
来源:https://stackoverflow.com/questions/15628632/an-array-is-subset-of-another-array