LCM of given array elements (original) (raw)

Given an array **a[] of **n numbers, find the Least Common Multiple (LCM) of all the elements of the array. The LCM of an array is the smallest positive number that is divisible by every element of the array.

**Examples:

**Input: a[] = [1, 2, 8, 3]
**Output: 24
**Explanation: 24 is the smallest number divisible by 1, 2, 8 and 3.

**Input: a[] = [1, 8]
**Output: 8
**Explanation: 8 is the smallest number divisible by both 1 and 8.

Table of Content

[Naive Approach] Checking Multiples - O(max(a[i]) * n) Time and O(1) Space

The idea is to find LCM of two numbers by iterating through multiples of the larger number until we find one that is also divisible by the smaller number. We then extend this to the whole array by iteratively finding LCM of the current result with the next element.

**Why can we compute LCM of an array one element at a time?

LCM satisfies the associative property:

LCM(a, b, c) = LCM(LCM(a, b), c)

**Proof: A number x is divisible by a, b and c if and only if x is divisible by LCM(a, b) and c. The smallest such x is LCM(LCM(a, b), c). This extends to any number of elements: LCM(a₁, a₂, ... aₙ) = LCM(LCM(... LCM(LCM(a₁, a₂), a₃) ...), aₙ)

**Example: arr = [1, 2, 8, 3]:
LCM(1, 2) = 2
LCM(2, 8) = 8
LCM(8, 3) = 24

C++ `

#include #include using namespace std;

int lcmOfTwo(int a, int b) {

// Start from the larger number
int res = max(a, b);

// Keep incrementing by the larger number until divisible by both
while (res % a != 0 || res % b != 0)
    res += max(a, b);

return res;

}

int lcmOfArray(vector &a) {

// Initialize res with first element
int res = a[0];

// Iteratively compute LCM of res with each element
for (int i = 1; i < (int)a.size(); i++)
    res = lcmOfTwo(res, a[i]);

return res;

}

int main() { vector a = {1, 2, 8, 3}; cout << lcmOfArray(a) << endl; return 0; }

Java

class GFG {

static int lcmOfTwo(int a, int b) {

    // Start from the larger number
    int res = Math.max(a, b);

    // Keep incrementing by the larger number until divisible by both
    while (res % a != 0 || res % b != 0)
        res += Math.max(a, b);

    return res;
}

static int lcmOfArray(int[] a) {

    // Initialize res with first element
    int res = a[0];

    // Iteratively compute LCM of res with each element
    for (int i = 1; i < a.length; i++)
        res = lcmOfTwo(res, a[i]);

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 8, 3};
    System.out.println(lcmOfArray(a));
}

}

Python

def lcmOfTwo(a, b):

# Start from the larger number
res = max(a, b)

# Keep incrementing by the larger number until divisible by both
while res % a != 0 or res % b != 0:
    res += max(a, b)

return res

def lcmOfArray(a):

# Initialize res with first element
res = a[0]

# Iteratively compute LCM of res with each element
for i in range(1, len(a)):
    res = lcmOfTwo(res, a[i])

return res

if name == "main": a = [1, 2, 8, 3] print(lcmOfArray(a))

C#

using System;

class GFG {

static int lcmOfTwo(int a, int b) {

    // Start from the larger number
    int res = Math.Max(a, b);

    // Keep incrementing by the larger number until divisible by both
    while (res % a != 0 || res % b != 0)
        res += Math.Max(a, b);

    return res;
}

static int lcmOfArray(int[] a) {

    // Initialize res with first element
    int res = a[0];

    // Iteratively compute LCM of res with each element
    for (int i = 1; i < a.Length; i++)
        res = lcmOfTwo(res, a[i]);

    return res;
}

static void Main() {
    int[] a = {1, 2, 8, 3};
    Console.WriteLine(lcmOfArray(a));
}

}

JavaScript

function lcmOfTwo(a, b) {

// Start from the larger number
let res = Math.max(a, b);

// Keep incrementing by the larger number until divisible by both
while (res % a !== 0 || res % b !== 0)
    res += Math.max(a, b);

return res;

}

function lcmOfArray(a) {

// Initialize res with first element
let res = a[0];

// Iteratively compute LCM of res with each element
for (let i = 1; i < a.length; i++)
    res = lcmOfTwo(res, a[i]);

return res;

}

// Driver code let a = [1, 2, 8, 3]; console.log(lcmOfArray(a));

`

[Expected Approach] Using GCD - O(n * log(max(a[i]))) Time and O(1) Space

The idea is to use the mathematical relation lcm(a, b) = (a / gcd(a, b)) * b to efficiently compute LCM of two numbers. We then extend this to the whole array by iteratively computing LCM of the current result with the next element using GCD.

**Why does LCM(a, b) = (a × b) / GCD(a, b)?

Every number can be expressed as a product of prime factors. GCD(a, b) contains the common prime factors and LCM(a, b) contains the all prime factors of both.

Since GCD × LCM covers all prime factors of both numbers exactly once:

GCD(a, b) × LCM(a, b) = a × b
Therefore:
LCM(a, b) = (a × b) / GCD(a, b) = (a / GCD(a, b)) × b

**Example: a=4, b=6:
4 = 22 , 6 = 2 × 3
GCD(4, 6) = 2 (common factors)
LCM(4, 6) = 22 × 3 = 12
**Verify: (4 × 6) / 2 = 12

**Note: We divide before multiplying (a / GCD) × b to avoid integer overflow.

C++ `

#include #include using namespace std;

int gcd(int a, int b) {

// Euclidean algorithm to find GCD
while (b)
{
    a = a % b;
    swap(a, b);
}
return a;

}

int lcmOfArray(vector &a) {

// Initialize res with first element
int res = a[0];

// Iteratively compute LCM using gcd relation
for (int i = 1; i < (int)a.size(); i++)
    res = (res / gcd(res, a[i])) * a[i];

return res;

}

int main() { vector a = {1, 2, 8, 3}; cout << lcmOfArray(a) << endl; return 0; }

Java

class GFG {

static int gcd(int a, int b) {

    // Euclidean algorithm to find GCD
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

static int lcmOfArray(int[] a) {

    // Initialize res with first element
    int res = a[0];

    // Iteratively compute LCM using gcd relation
    for (int i = 1; i < a.length; i++)
        res = (res / gcd(res, a[i])) * a[i];

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 8, 3};
    System.out.println(lcmOfArray(a));
}

}

Python

def gcd(a, b):

# Euclidean algorithm to find GCD
while b:
    a, b = b, a % b
return a

def lcmOfArray(a):

# Initialize res with first element
res = a[0]

# Iteratively compute LCM using gcd relation
for i in range(1, len(a)):
    res = (res // gcd(res, a[i])) * a[i]

return res

if name == "main": a = [1, 2, 8, 3] print(lcmOfArray(a))

C#

using System;

class GFG {

static int gcd(int a, int b) {

    // Euclidean algorithm to find GCD
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

static int lcmOfArray(int[] a) {

    // Initialize res with first element
    int res = a[0];

    // Iteratively compute LCM using gcd relation
    for (int i = 1; i < a.Length; i++)
        res = (res / gcd(res, a[i])) * a[i];

    return res;
}

static void Main() {
    int[] a = {1, 2, 8, 3};
    Console.WriteLine(lcmOfArray(a));
}

}

JavaScript

function gcd(a, b) {

// Euclidean algorithm to find GCD
while (b) {
    [a, b] = [b, a % b];
}
return a;

}

function lcmOfArray(a) {

// Initialize res with first element
let res = a[0];

// Iteratively compute LCM using gcd relation
for (let i = 1; i < a.length; i++)
    res = (res / gcd(res, a[i])) * a[i];

return res;

}

// Driver code let a = [1, 2, 8, 3]; console.log(lcmOfArray(a));

`