Maximum length subarray with LCM equal to product

Given an arr[], the task is to find the maximum length of the sub-array such that the LCM of the sub-array is equal to the product of numbers in the sub-array. If no valid sub-array exists, then print -1.Â
Note: The length of the sub-array must be ? 2.
Examples:Â Â
Input: arr[] = { 6, 10, 21}Â
Output: 2Â
The sub-array { 10, 21 } satisfies the condition.Input: arr[] = { 2, 2, 4}Â
Output: -1Â
No sub-array satisfies the condition. Hence, the output is -1.Â
Naive Approach: Run nested loops to check the condition for every possible sub-array of length ? 2. If the sub-array satisfies the condition, then update ans = max(ans, length(sub-array)). Print the ans in the end.
Below is the implementation of the above approach:Â Â
C++
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std;Â
#define ll long longÂ
// Function to calculate gcd(a, b)int gcd(int a, int b){Â Â Â Â if (b == 0)Â Â Â Â Â Â Â Â return a;Â Â Â Â return gcd(b, a % b);}Â
// Function to return max length of subarray// that satisfies the conditionint maxLengthSubArray(const int* arr, int n){Â Â Â Â int maxLen = -1;Â Â Â Â for (int i = 0; i < n - 1; i++) {Â Â Â Â Â Â Â Â for (int j = i + 1; j < n; j++) {Â Â Â Â Â Â Â Â Â Â Â Â ll lcm = 1LL * arr[i];Â Â Â Â Â Â Â Â Â Â Â Â ll product = 1LL * arr[i];Â
            // Update LCM and product of the            // sub-array            for (int k = i + 1; k <= j; k++) {                lcm = (((arr[k] * lcm)) /                           (gcd(arr[k], lcm)));                product = product * arr[k];            }Â
            // If the current sub-array satisfies             // the condition            if (lcm == product) {Â
                // Choose the maximum                maxLen = max(maxLen, j - i + 1);            }        }    }Â
    return maxLen;}Â
// Driver codeint main(){Â Â Â Â int arr[] = { 6, 10, 21 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â Â Â Â cout << maxLengthSubArray(arr, n);Â Â Â Â return 0;} |
Java
// Java implementation of the above approachimport java.util.*;Â
class GFG{Â
// Function to calculate gcd(a, b)static int gcd(int a, int b){Â Â Â Â if (b == 0)Â Â Â Â Â Â Â Â return a;Â Â Â Â return gcd(b, a % b);}Â
// Function to return max length of subarray// that satisfies the conditionstatic int maxLengthSubArray(int arr[], int n){Â Â Â Â int maxLen = -1;Â Â Â Â for (int i = 0; i < n - 1; i++) Â Â Â Â {Â Â Â Â Â Â Â Â for (int j = i + 1; j < n; j++) Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â int lcm = 1 * arr[i];Â Â Â Â Â Â Â Â Â Â Â Â int product = 1 * arr[i];Â
            // Update LCM and product of the            // sub-array            for (int k = i + 1; k <= j; k++)                          {                lcm = (((arr[k] * lcm)) /                         (gcd(arr[k], lcm)));                product = product * arr[k];            }Â
            // If the current sub-array satisfies             // the condition            if (lcm == product)            {Â
                // Choose the maximum                maxLen = Math.max(maxLen, j - i + 1);            }        }    }    return maxLen;}Â
// Driver codepublic static void main(String args[]){Â Â Â Â int arr[] = { 6, 10, 21 };Â Â Â Â int n = arr.length;Â Â Â Â System.out.println(maxLengthSubArray(arr, n));}}Â
// This code is contributed by// Shashank_Sharma |
Python3
# Python3 implementation of the # above approachÂ
# Function to calculate gcd(a, b)def gcd(a, b):    if (b == 0):        return a    return gcd(b, a % b)Â
# Function to return max length of # subarray that satisfies the conditiondef maxLengthSubArray(arr, n):Â
    maxLen = -1    for i in range(n - 1):        for j in range(n):            lcm = arr[i]            product = arr[i]Â
            # Update LCM and product of the            # sub-array            for k in range(i + 1, j + 1):                lcm = (((arr[k] * lcm)) //                    (gcd(arr[k], lcm)))                product = product * arr[k]                         # If the current sub-array satisfies             # the condition            if (lcm == product): Â
                # Choose the maximum                maxLen = max(maxLen, j - i + 1)    return maxLenÂ
# Driver codearr = [6, 10, 21 ]n = len(arr)print(maxLengthSubArray(arr, n))Â
# This code is contributed by # mohit kumar 29 |
C#
// C# implementation of the above approachusing System;Â
class GFG{Â
// Function to calculate gcd(a, b)static int gcd(int a, int b){Â Â Â Â if (b == 0)Â Â Â Â Â Â Â Â return a;Â Â Â Â return gcd(b, a % b);}Â
// Function to return max length of subarray// that satisfies the conditionstatic int maxLengthSubArray(int[] arr, int n){Â Â Â Â int maxLen = -1;Â Â Â Â for (int i = 0; i < n - 1; i++) Â Â Â Â {Â Â Â Â Â Â Â Â for (int j = i + 1; j < n; j++) Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â int lcm = 1 * arr[i];Â Â Â Â Â Â Â Â Â Â Â Â int product = 1 * arr[i];Â
            // Update LCM and product of the            // sub-array            for (int k = i + 1; k <= j; k++)                          {                lcm = (((arr[k] * lcm)) /                         (gcd(arr[k], lcm)));                product = product * arr[k];            }Â
            // If the current sub-array satisfies             // the condition            if (lcm == product)            {Â
                // Choose the maximum                maxLen = Math.Max(maxLen, j - i + 1);            }        }    }    return maxLen;}Â
// Driver codepublic static void Main(){Â Â Â Â int[] arr = { 6, 10, 21 };Â Â Â Â int n = arr.Length;Â Â Â Â Console.Write(maxLengthSubArray(arr, n));}}Â
// This code is contributed by ita_c |
PHP
<?php// PHP implementation of the above approachÂ
// Function to calculate gcd(a, b)function gcd($a, $b){Â Â Â Â if ($b == 0)Â Â Â Â Â Â Â Â return $a;Â Â Â Â return gcd($b, $a % $b);}Â
// Function to return max length of subarray// that satisfies the conditionfunction maxLengthSubArray(&$arr, $n){Â Â Â Â $maxLen = -1;Â Â Â Â for ($i = 0; $i < $n - 1; $i++) Â Â Â Â {Â Â Â Â Â Â Â Â for ($j = $i + 1; $j < $n; $j++) Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â $lcm = $arr[$i];Â Â Â Â Â Â Â Â Â Â Â Â $product = $arr[$i];Â
            // Update LCM and product of the            // sub-array            for ($k = $i + 1; $k <= $j; $k++)            {                $lcm = ((($arr[$k] * $lcm)) /                         (gcd($arr[$k], $lcm)));                $product = $product * $arr[$k];            }Â
            // If the current sub-array satisfies             // the condition            if ($lcm == $product)            {Â
                // Choose the maximum                $maxLen = max($maxLen, $j - $i + 1);            }        }    }Â
    return $maxLen;}Â
// Driver code$arr = array(6, 10, 21 );$n = sizeof($arr);echo(maxLengthSubArray($arr, $n));Â
// This code is contributed by Shivi_Aggarwal?> |
Javascript
<script>// Javascript implementation of the above approachÂ
// Function to calculate gcd(a, b)function gcd(a,b){    if (b == 0)        return a;    return gcd(b, a % b);}Â
// Function to return max length of subarray// that satisfies the conditionfunction maxLengthSubArray(arr,n){    let maxLen = -1;    for (let i = 0; i < n - 1; i++)    {        for (let j = i + 1; j < n; j++)        {            let lcm = 1 * arr[i];            let product = 1 * arr[i];              // Update LCM and product of the            // sub-array            for (let k = i + 1; k <= j; k++)                          {                lcm = (((arr[k] * lcm)) /                        (gcd(arr[k], lcm)));                product = product * arr[k];            }              // If the current sub-array satisfies            // the condition            if (lcm == product)            {                  // Choose the maximum                maxLen = Math.max(maxLen, j - i + 1);            }        }    }    return maxLen;}Â
// Driver codelet arr=[6, 10, 21 ];let n = arr.length;document.write(maxLengthSubArray(arr, n));Â Â Â Â Â Â
// This code is contributed by unknown2108</script> |
2
Â
Efficient Approach: A sub-array will have its LCM equal to its product when no two elements in the sub-array have any common factor.Â
For example:Â Â
arr[] = { 6, 10, 21 }
Prime factorization yields:Â
arr[] = { 2 * 3, 2 * 5, 3 * 7 }
[6, 10] has 2 as a common factor.Â
[6, 10, 21] has 2 as a common factor between 6 and 10.Â
Sub-array [10, 21] has no common factor between any 2 elements. Therefore, answer = 2. Â
Firstly, prime factorization of numbers is done to deal with factors. To calculate the sub-array in which no 2 elements have a common factor, we use the two-pointer technique.Â
Two pointers run, both from the right and they represent the current sub-array. We add elements in the sub-array from the right. Now there are two scenarios:Â Â
- An element is added in the current sub-array if it has no factor in common with the current elements in the sub-array. If a common factor is found, then starting from the left, elements are subsequently eliminated until no common factor is found with the newly added element.
- If there are no common factors between the newly added element and existing elements, then update ans = max(ans, length of sub-array)
Below is the implementation of the above approach:Â Â
C++
// C++ implementation of the above approach#include <bits/stdc++.h>Â
#define pb push_back#define N 100005#define MAX 1000002#define mem(a, b) memset(a, b, sizeof(a))Â
using namespace std;Â
int prime[MAX];Â
// Stores array of primes for every elementvector<int> v[N];Â
// Stores the position of a prime in the subarray// in two pointer techniqueint f[MAX];Â
// Function to store smallest prime factor of numbersvoid sieve(){Â Â Â Â prime[0] = prime[1] = 1;Â Â Â Â for (int i = 2; i < MAX; i++) {Â Â Â Â Â Â Â Â if (!prime[i]) {Â Â Â Â Â Â Â Â Â Â Â Â for (int j = i * 2; j < MAX; j += i) {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (!prime[j])Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â prime[j] = i;Â Â Â Â Â Â Â Â Â Â Â Â }Â Â Â Â Â Â Â Â }Â Â Â Â }Â
    for (int i = 2; i < MAX; i++) {Â
        // If number is prime,        // then smallest prime factor is the        // number itself        if (!prime[i])            prime[i] = i;    }}Â
// Function to return maximum length of subarray// with LCM = productint maxLengthSubArray(int* arr, int n){Â Â Â Â // Initialize f with -1Â Â Â Â mem(f, -1);Â
    for (int i = 0; i < n; ++i) {Â
        // Prime factorization of numbers        // Store primes in a vector for every element        while (arr[i] > 1) {            int p = prime[arr[i]];            arr[i] /= p;            v[i].pb(p);        }    }Â
    // Two pointers l and r     // denoting left and right of subarray    int l = 0, r = 1, ans = -1;Â
    // f is a mapping.    // prime -> index in the current subarray    // With the help of f,    // we can detect whether a prime has    // already occurred in the subarray    for (int i : v[0]) {        f[i] = 0;    }Â
    while (l <= r && r < n) {        int flag = 0;Â
        for (int i = 0; i < v[r].size(); i++) {Â
            // Map the prime to the index            if (f[v[r][i]] == -1 || f[v[r][i]] == r) {                f[v[r][i]] = r;            }Â
            // If already occurred then,            // start removing elements from the left            else {                flag = 1;                break;            }        }Â
        // Remove elements if flag = 1        if (flag) {Â
            // Nullify entries of element at index 'l'            for (int i : v[l]) {                f[i] = -1;            }Â
            // Increment 'l'            l++;        }        else {Â
            // Maximize the answer when            // no common factor is found            ans = max(ans, r - l + 1);            r++;        }    }Â
    // One length subarray is discarded    if (ans == 1)        ans = -1;Â
    return ans;}Â
// Driver codeint main(){Â Â Â Â sieve();Â Â Â Â int arr[] = { 6, 10, 21 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â Â Â Â cout << maxLengthSubArray(arr, n);Â Â Â Â return 0;} |
Java
// Java implementation of the above approachimport java.io.*;import java.util.*;Â
class GFG{Â Â Â Â Â static int N = 100005;static int MAX = 1000002;static int[] prime = new int[MAX];Â
// Stores array of primes for every element static ArrayList<Â Â Â Â Â Â Â ArrayList<Integer>> v = new ArrayList<Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ArrayList<Integer>>();Â
// Stores the position of a prime in the // subarray in two pointer techniquestatic int[] f = new int[MAX];Â
// Function to store smallest prime // factor of numbers static void sieve(){    for(int i = 0; i < N; i++)    {        v.add(new ArrayList<Integer>());    }         prime[0] = prime[1] = 1;          for(int i = 2; i < MAX; i++)    {        if (prime[i] == 0)        {            for(int j = i * 2; j < MAX; j += i)            {                if (prime[j] == 0)                {                    prime[j] = i;                }            }        }    }         for(int i = 2; i < MAX; i++)    {                 // If number is prime, then         // smallest prime factor is         // the number itself         if (prime[i] == 0)        {            prime[i] = i;         }    }}Â
// Function to return maximum length of// subarray with LCM = product static int maxLengthSubArray(int[] arr, int n) {         // Initialize f with -1     Arrays.fill(f, -1);         for(int i = 0; i < n; ++i)    {                 // Prime factorization of numbers         // Store primes in a vector for        // every element         while (arr[i] > 1)        {            int p = prime[arr[i]];            arr[i] /= p;            v.get(i).add(p);        }    }         // Two pointers l and r denoting    // left and right of subarray    int l = 0, r = 1, ans = -1;         // f is a mapping.     // prime -> index in the current subarray     // With the help of f,     // we can detect whether a prime has     // already occurred in the subarray     for(int i : v.get(0))    {        f[i] = 0;    }         while (l <= r && r < n)    {        int flag = 0;                 for(int i = 0; i < v.get(r).size(); i++)        {                         // Map the prime to the index             if (f[v.get(r).get(i)] == -1 ||                 f[v.get(r).get(i)] == r)            {                f[v.get(r).get(i)] = r;            }                         // If already occurred then,             // start removing elements             // from the left             else            {                flag = 1;                break;             }        }                 // Remove elements if flag = 1         if (flag != 0)        {                         // Nullify entries of element            // at index 'l'             for(int i : v.get(l))            {                f[i] = -1;            }                         // Increment 'l'             l++;         }        else        {                         // Maximize the answer when             // no common factor is found            ans = Math.max(ans, r - l + 1);            r++;        }             }         // One length subarray is discarded     if (ans == 1)     {        ans = -1;     }    return ans; }Â
// Driver code public static void main(String[] args) {Â Â Â Â sieve();Â Â Â Â int arr[] = { 6, 10, 21 };Â Â Â Â int n = arr.length;Â Â Â Â Â Â Â Â Â System.out.println(maxLengthSubArray(arr, n));}}Â
// This code is contributed by avanitrachhadiya2155 |
Python3
# Python3 implementation of the above approachÂ
N = 100005MAX = 1000002Â
Â
Â
prime = [0 for i in range(MAX + 1)]Â
# Stores array of primes for every elementv = [[] for i in range(N)]Â
# Stores the position of a prime in the subarray# in two pointer techniquef = [-1 for i in range(MAX)]Â
# Function to store smallest prime factor of numbersdef sieve():Â
    prime[0], prime[1] = 1, 1Â
    for i in range(2, MAX + 1):        if (prime[i] == 0):            for j in range(i * 2, MAX, i):                if (prime[j] == 0):                    prime[j] = iÂ
Â
    for i in range(2, MAX):Â
        # If number is prime,        # then smallest prime factor is the        # number itself        if (prime[i] == 0):            prime[i] = iÂ
# Function to return maximum length of subarray# with LCM = productdef maxLengthSubArray(arr, n):Â Â Â Â Â Â Â Â Â # Initialize f with -1Â Â Â Â for i in range(n):Â Â Â Â Â Â Â Â f[i] = -1Â
    for i in range(n):Â
        # Prime factorization of numbers        # Store primes in a vector for every element        while (arr[i] > 1):            p = prime[arr[i]]            arr[i] //= p            v[i].append(p)Â
    # Two pointers l and r    # denoting left and right of subarray    l, r, ans = 0, 1, -1Â
    # f is a mapping.    # prime -> index in the current subarray    # With the help of f,    # we can detect whether a prime has    # already occurred in the subarray    for i in v[0]:        f[i] = 0Â
    while (l <= r and r < n):        flag = 0Â
        for i in range(len(v[r])):Â
            # Map the prime to the index            if (f[v[r][i]] == -1 or f[v[r][i]] == r):                f[v[r][i]] = rÂ
            # If already occurred then,            # start removing elements from the left            else:                flag = 1                breakÂ
        # Remove elements if flag = 1        if (flag):Â
            # Nullify entries of element at index 'l'            for i in v[l]:                f[i] = -1Â
            # Increment 'l'            l += 1        else :Â
            # Maximize the answer when            # no common factor is found            ans = max(ans, r - l + 1)            r += 1Â
Â
    # One length subarray is discarded    if (ans == 1):        ans = -1Â
    return ansÂ
# Driver codesieve()arr = [6, 10, 21]n = len(arr)print(maxLengthSubArray(arr, n))Â
# This code is contributed by mohit kumar |
C#
// C# implementation of the above approachusing System;using System.Collections.Generic;class GFG{Â
  static int N = 100005;  static int MAX = 1000002;  static int[] prime = new int[MAX];Â
  // Stores array of primes for every element   static List<List<int>> v = new List<List<int>>();Â
  // Stores the position of a prime in the   // subarray in two pointer technique  static int[] f = new int[MAX];Â
  // Function to store smallest prime   // factor of numbers   static void sieve()  {    for(int i = 0; i < N; i++)    {      v.Add(new List<int>());    }Â
    prime[0] = prime[1] = 1; Â
    for(int i = 2; i < MAX; i++)    {      if (prime[i] == 0)      {        for(int j = i * 2; j < MAX; j += i)        {          if (prime[j] == 0)          {            prime[j] = i;          }        }      }    }Â
    for(int i = 2; i < MAX; i++)    {Â
      // If number is prime, then       // smallest prime factor is       // the number itself       if (prime[i] == 0)      {        prime[i] = i;       }    }  }Â
  // Function to return maximum length of  // subarray with LCM = product   static int maxLengthSubArray(int[] arr, int n)   {    // Initialize f with -1     Array.Fill(f, -1);       for(int i = 0; i < n; ++i)    {Â
      // Prime factorization of numbers       // Store primes in a vector for      // every element       while (arr[i] > 1)      {        int p = prime[arr[i]];        arr[i] /= p;        v[i].Add(p);      }    }Â
    // Two pointers l and r denoting    // left and right of subarray    int l = 0, r = 1, ans = -1;Â
    // f is a mapping.     // prime -> index in the current subarray     // With the help of f,     // we can detect whether a prime has     // already occurred in the subarray Â
    foreach(int i in v[0])    {      f[i] = 0;    }Â
    while (l <= r && r < n)    {      int flag = 0;              for(int i = 0; i < v[r].Count; i++)      {Â
        // Map the prime to the index         if (f[v[r][i]] == -1 ||             f[v[r][i]] == r)        {          f[v[r][i]] = r;        }Â
        // If already occurred then,         // start removing elements         // from the left         else        {          flag = 1;          break;         }      }Â
      // Remove elements if flag = 1       if (flag != 0)      {Â
        // Nullify entries of element        // at index 'l'         foreach(int i in v[l])        {          f[i] = -1;        }Â
        // Increment 'l'         l++;       }      else      {Â
        // Maximize the answer when         // no common factor is found        ans = Math.Max(ans, r - l + 1);        r++;      }Â
    }Â
    // One length subarray is discarded     if (ans == 1)     {      ans = -1;     }    return ans;   }Â
  // Driver code  static public void Main ()  {    sieve();    int[] arr = { 6, 10, 21 };    int n = arr.Length;    Console.WriteLine(maxLengthSubArray(arr, n));  }}// This code is contributed by rag2127 |
Javascript
<script>// Javascript implementation of the above approachÂ
let N = 100005;let MAX = 1000002;let prime = new Array(MAX);for(let i=0;i<prime.length;i++){Â Â Â Â prime[i]=0;}// Stores array of primes for every elementlet v = [];Â
// Stores the position of a prime in the// subarray in two pointer techniquelet f = new Array(MAX);Â
// Function to store smallest prime// factor of numbersfunction sieve(){    for(let i = 0; i < N; i++)    {        v.push([]);    }          prime[0] = prime[1] = 1;          for(let i = 2; i < MAX; i++)    {        if (prime[i] == 0)        {            for(let j = i * 2; j < MAX; j += i)            {                if (prime[j] == 0)                {                    prime[j] = i;                }            }        }    }          for(let i = 2; i < MAX; i++)    {                  // If number is prime, then        // smallest prime factor is        // the number itself        if (prime[i] == 0)        {            prime[i] = i;        }    }}Â
// Function to return maximum length of// subarray with LCM = productfunction maxLengthSubArray(arr,n){     // Initialize f with -1    for(let i=0;i<f.length;i++)    {        f[i]=-1;    }          for(let i = 0; i < n; ++i)    {                  // Prime factorization of numbers        // Store primes in a vector for        // every element        while (arr[i] > 1)        {            let p = prime[arr[i]];            arr[i] /= p;            v[i].push(p);        }    }          // Two pointers l and r denoting    // left and right of subarray    let l = 0, r = 1, ans = -1;          // f is a mapping.    // prime -> index in the current subarray    // With the help of f,    // we can detect whether a prime has    // already occurred in the subarray    for(let i=0;i< v[0].length;i++)    {        f[v[0][i]] = 0;    }          while (l <= r && r < n)    {        let flag = 0;                  for(let i = 0; i < v[r].length; i++)        {                          // Map the prime to the index            if (f[v[r][i]] == -1 ||                f[v[r][i]] == r)            {                f[v[r][i]] = r;            }                          // If already occurred then,            // start removing elements            // from the left            else            {                flag = 1;                break;            }        }                  // Remove elements if flag = 1        if (flag != 0)        {                          // Nullify entries of element            // at index 'l'            for(let i=0;i<v[l].length;i++)            {                f[v[l][i]] = -1;            }                          // Increment 'l'            l++;        }        else        {                          // Maximize the answer when            // no common factor is found            ans = Math.max(ans, r - l + 1);            r++;        }              }          // One length subarray is discarded    if (ans == 1)    {        ans = -1;    }    return ans;}Â
// Driver codeÂ
sieve();let arr=[ 6, 10, 21];let n = arr.length;document.write(maxLengthSubArray(arr, n));Â
Â
// This code is contributed by patel2127</script> |
2
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



