问题
I came across a coding quiz, given two no A and B find the nth HCF of the two no
for eg 16 , 8
HCF 8, 4, 2, 1 so 3rd HCF is 2
I solved like this
1. X = GCD(A,B)
2. Find all factor of X
3. Sort the factor in order
But I want to know better approach
Thanks
回答1:
I think that the approach you have mentioned in description above is optimal except for the last step where you essentially do not need to sort the factors - you can simply generate them in increasing order.
You can read this interesting discussion on complexity of Euclid Algorithm which is the time complexity for your first step. Once GCD has been computed, finding all its factors will take O(sqrt(gcd)) time. You can generate them in increasing order as follows:
public ArrayList<Integer> factorize(int x) {
ArrayList<Integer> factors_left = new ArrayList<>();
ArrayList<Integer> factors_right = new ArrayList<>();
for(int i=1; i<=(int)sqrt(x)+1; i++) {
if(x%i==0) {
factors_left.add(i);
factors_right.add(x/i);
}
}
ArrayList<Integer> allfactors = new ArrayList<>();
for(int f: factors_left) {
allfactors.add(f);
}
for(int i=factors_right.size()-1; i>=0; i--) {
allfactors.add(factors_right.get(i));
}
return allfactors;
}
You can now simply traverse this list to find the desired factor.
回答2:
You can derive your list of common factors from the prime factors of the hcf of the two numbers.
Here's a demo using code I had lying around. I use an implementation of the Extended Euclidean algorithm for the GCD just because I had one available. It's not necessarily the fastest solution.
/**
* Prime factors of the number - not the most efficient but it works.
*
* @param n - The number to factorise.
* @return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n) {
return primeFactors(n, false);
}
/**
* Prime factors of the number - not the most efficient but it works.
*
* @param n - The number to factorise.
* @param unique - Want only unique factors.
* @return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n, boolean unique) {
Collection<Long> factors;
if (unique) {
factors = new HashSet<>();
} else {
factors = new ArrayList<>();
}
for (long i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
if (n > 1) {
factors.add(n);
}
return new ArrayList<>(factors);
}
/**
* Extended Euclidean algorithm to find the GCD of a and b.
*
* We assume here that a and b are non-negative (and not both zero).
*
* This function also will return numbers j and k such that d = j*a + k*b where d is the GCD of a and b.
*/
public static int[] extendedEuclid(int a, int b) {
int[] ans = new int[3];
int q;
// If b = 0, then we're done...
if (b == 0) {
// All over.
ans[0] = a;
ans[1] = 1;
ans[2] = 0;
} else {
// Otherwise, make a recursive function call
q = a / b;
ans = extendedEuclid(b, a % b);
int temp = ans[1] - ans[2] * q;
ans[1] = ans[2];
ans[2] = temp;
}
return ans;
}
/**
* Common factors of the GCD of the two numbers.
*
* @param a - First number.
* @param b - Second number.
* @return - List of common factors.
*/
public static List<Long> cfs(int a, int b) {
return primeFactors(extendedEuclid(a, b)[0]);
}
private static void test(int a, int b) {
// Get the GCD.
int[] ee = extendedEuclid(a, b);
System.out.println("eEu(" + a + "," + b + ") = " + Arrays.toString(ee));
// Get common factors.
List<Long> cfs = cfs(a, b);
System.out.println("cfs(" + a + "," + b + ") = " + cfs);
// Build your list of what you call HCFs.
List<Long> hcfs = new ArrayList<>();
// Start at the GCD.
long hcf = ee[0];
for (Long l : cfs) {
// Record that factor.
hcfs.add(hcf);
// Remove this prime factor from it.
hcf /= l;
// Obviously you could stop when you have your nth one.
}
// Also add `1`
hcfs.add(1l);
System.out.println("hcfs(" + a + "," + b + ") = " + hcfs);
}
public void test() {
test(16, 8);
test(144, 72);
}
This prints:
eEu(16,8) = [8, 0, 1]
cfs(16,8) = [2, 2, 2]
hcfs(16,8) = [8, 4, 2, 1]
eEu(144,72) = [72, 0, 1]
cfs(144,72) = [2, 2, 2, 3, 3]
hcfs(144,72) = [72, 36, 18, 9, 3, 1]
回答3:
Like what Bhoot said but even better: find all the factors up to sqrt(x) in an increasing order, like Bhoot factors_left.
Now for nth HCF you just get X / factors_left[n].
来源:https://stackoverflow.com/questions/30368939/nth-hcf-of-two-number