Facebook Interview Question
Software Engineer / DevelopersI know that is true for 2 numbers. But not sure if that is right for array at same time.
For e.g. take numbers: 2,4,6 : LCM is 12 and GCD is 2.
Ofcourse, even with your solution, you have to give answer to find GCD.
I think for this, we first sort the given numbers ascending.
Idea is to divide the whole series by 2 or 3 iteratively till we convert the first number into a prime number.
Ofcourse when we divide, if a number is not divisible by 2, then leave as it is and proceed to next number which is divisible by 2(with remainder 0). Remember number of 2's and 3's we used to divide. Example below:
So if input is 10,9,15.
Sort it 9,10,15
Divide by 2: 9,5,15 (Only 10 was divisible)
No more evens, so done with 2.
Divide by 3: 3,5,5
Divide by 3: 1,5,5
First number is prime (cannot be divided by 2 or 3). So stop. LCM is 2 * 3 * 3 * 5 * 5 = 450
Simply multiple all the numbers.
You will get a result. Divide the number by the first element. If the resultant number is divisible by other numbers as well, then the resultant number is the lcm.
Do this process till the resultant number is not divisble by one of the element.
Output the resultant number as LCM.
@santos
"I know that is true for 2 numbers. But not sure if that is right for array at same time."
No it is wrong for more than 2 numbers
gcd <= smallest number ; lcm>=largest number
further gcd * lcm = x*y
all these properties can be seen very easily if you know that gcd=product (prime(least power))
lcm=product(prime(highest power))
(least, highest) in the prime factorization of individual numbers, for all unique primes seen
@Kishore: LCM is 90 for your example. I got similar kind of idea after looking your approach.
1. Minheapify the array.
2. Divide all the elements of array till first element becomes 1 at the same time maintain count for all prime divisors.
3. exchange 1st element to last and decrease array size.
4. if array size is is not zero go to 1 else stop.
So after step 1 - 4 if we have count n1,n2,n3 for primes p1,p2,p3 then the LCM is
LCM=p1*p1*..n1times * p2*p2*..n2 times, p3*p3*...n3times.
e.g.
Array = 10, 9 15, size is 3.
step 1 9,10,15 size 3 prime divisor none
step 2 3,10,5 size 3 prime divisors 3-->1
step 2 1,10,5 size 3 prime divisors 3-->2
step 3 5,10,1 size 2 prime divisors 3-->2
step 4 go to 1.
step 1 5,10,1 size 2 prime divisors 3-->2
step 2 1,2,1 size 2 prime divisors 3-->2 5-->1
step 3 2,1,1 size 1 prime divisors 3-->2 5-->1
step 4 go to 1
step 1 2,1,1 size 1 prime divisors 3-->2 5-->1
step 2 1,1,1 size 2 prime divisors 3-->2 5-->1 2-->1
step 3 1,1,1 size 0
step 4 STOP
LCM = 3*3*2*5 = 90
step 1 : LCM (10,9) = 10 * 9 / GCD (10,9) = 90
step 2 : LCM (90, 15) = 90*15 / GCD(90,15) = 90
@Tulley,
You are right. After the final step, we could divide it by 5, another prime and result would be 450/5 = 90
@Tulley,
You are right. After the final step, we could divide it by 5, another prime and result would be 450/5 = 90
@Tulley,
You are right. After the final step, we could divide it by 5, another prime and result would be 450/5 = 90
Based on Eric Xu's comment:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
unsigned int gcd(unsigned int a, unsigned int b)
{
while(a != 0 && b != 0)
{
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a + b;
}
unsigned int lcm(std::vector<unsigned int>&num)
{
if (num.empty())
{
printf("unable to calculate LCM for empty vector\n");
exit(1);
}
else if (num.size() == 1)
{
return num.back();
}
else
{
unsigned int a = num.back();
num.pop_back();
unsigned int b = num.back();
num.pop_back();
unsigned int x = a * b / gcd(a, b);
num.push_back(x);
return lcm(num);
}
}
int main()
{
std::vector<unsigned int>num;
num.push_back(10);
num.push_back(9);
num.push_back(15);
printf("%d\n", lcm(num));
}
Here is an iterative version based on Xu's comment, also would it be a little faster if mod-based GCD computation is used instead of subtraction-based?
int GetGCD(int a, int b) {
int aa = a;
int bb = b;
while (bb != 0) {
int tmp = bb;
bb = aa % bb;
aa = tmp;
}
return aa;
}
int main(int argc, char** argv) {
int array[3] = {10,9,15};
vector<int> A(array, array+3);
int n = A.size();
int lcm;
int left_operand = A[0];
for (int i = 1; i < n; ++i) {
int prod = left_operand * A[i];
int gcd = GetGCD(left_operand, A[i]);
lcm = prod / gcd;
left_operand = lcm;
}
return lcm;
}
have a simple code for LCM
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
void main()
{
int i=2,j,n,*num,ct=0,lcm;
printf("Enter the total no:");
scanf("%d",&n);
if(n==0)
{
printf("Total no should be more then ZERO");
getch();
exit(1);
}
num=(int *)malloc(n*2);
for(i=0;i<=n-1;i++)
{
printf("enter the %d number:",i+1) ;
scanf("%d",&num[i]);
}
i=2;
while(i)
{
for(j=0,ct=0;j<=n-1;j++)
{
if(i%num[j]==0)
ct=ct+1;
}
if(ct==n)
{
lcm=i;
break;
}
i++;
}
printf("\nlcm=%d",lcm);
}
int LCM(int d,int e)
{
int a=d,b=e,c,lcm;
while((a=a%b)!=0)
{
c=a;
a=b;
b=c;
}
lcm=(d*e)/b;
return lcm;
}
in main function()
{
for(i=2;i<b;i++)
lcm=LCM(lcm,a[i]);
}
I have a solution that doesn't require any prime test. Basically note that
- Eric Xu March 03, 2011LCM (a, b, c) = LCM(LCM (a, b), c)
This is easy to prove: basically LCM(a, b) takes the maximum index in the prime factorization of a, b. LCM(a, b, c) takes the maximum index of all possible primes in a, b, and c, which is equivalent to finding the maximum index of primes from a, b and then c.
Based on these, and the fact that LCM(a, b) = a * b / GCD(a, b), we can do an iterative algorithm that only requires a GCD procedure, which can be easily done using the Euclid's algorithm.