I've written an implementation for the Sherlock GCD HackerRank Challenge. As the running time of my algorithm is something like \$O(kn^2)\$, I reckon that there's a more efficient algorithm that could be used instead. Are there any improvements that can be made to my implementation to reduce the running time?
Problem statement (as shown on HackerRank)
Sherlock is stuck while solving a problem: Given an array \$A={a1,a2,⋯,aN}\$, he wants to know if there exists a subset \$B\$ of this array which follows these statements:
- \$B\$ is a non-empty subset.
- There exists no integer \$x(x>1)\$ which divides all elements of \$B\$.
- There are no elements of \$B\$ which are equal to another.
YES
if such a subset exists; otherwise, printNO
Answer:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SherlockGCD {
public static void main(String[] args) {
try(BufferedReader input = new BufferedReader(new InputStreamReader(System.in))){
int numTestCases = Integer.parseInt(input.readLine());
for(int i = 0; i < numTestCases; i++){
int N = Integer.parseInt(input.readLine());
String[] array = input.readLine().split(" ");
Set<Integer> distinctElements = new HashSet<>(N);
for(int j = 0; j < N; j++){
distinctElements.add(Integer.valueOf(array[j]));
}
List<Integer> numbers = new ArrayList<>(distinctElements);
System.out.println(doesSubsetExist(distinctElements, numbers));
}
}catch(IOException e){
e.printStackTrace();
}
}
/**
* Determines whether a subset that satisfies the constraints in the problem statement exists.
*
* Looks for two elements that satisfy the conditions set out in the problem statement. If two such
* elements exist, then there exists at least one subset that satisfies the conditions. Else, there doesn't exist a
* subset.
*
* @param set A set of distinct numbers. Passed in because .contains() is O(1) for a Set vs O(n) for an
* ArrayList
* @param numbers A list of distinct numbers
* @return "YES" if such a subset exists. "NO" if not.
*/
private static String doesSubsetExist(Set<Integer> set, List<Integer> numbers){
if(set.contains(1)){
return "YES";
}
// If there's only one distinct element and that element isn't the integer 1, then the second constraint is not
// satisfied.
if(numbers.size() == 1){
return "NO";
}
for(int i = 0; i < numbers.size(); i++){
for(int j = i + 1; j < numbers.size(); j++){
for(int k = 2; k <= Math.min(numbers.get(i), numbers.get(j)); k++){
if(numbers.get(i) % k == 0 && numbers.get(j) % k == 0){
break;
}
if(k == Math.min(numbers.get(i), numbers.get(j))){
return "YES";
}
}
}
}
return "NO";
}
}