Skip to content
Related Articles

Related Articles

Improve Article

Minimum index to split array into subarrays with co-prime products

  • Last Updated : 18 May, 2021

Given an array arr[] consisting of N integers, the task is to find the maximum index K such that the product of subarrays {arr[0], arr[K]} and {arr[K + 1], arr[N – 1]} are co-prime. If no such index exists, then print “-1”.

Examples:

Input: arr[] = {2, 3, 4, 5}
Output: 2
Explanation:
Smallest index for partition is 2.
Product of left subarray is = 2 * 3 * 4 = 24.
Product of right subarray = 5.
Since 24 and 5 are co-prime, the required answer is 2.

Input: arr[] = {23, 41, 52, 83, 7, 13}
Output: 0
Explanation:
Smallest index for partition is 0.
Product of left subarray = 23.
Product of right subarray = 41 * 52 * 83 * 7 * 13 = 16102996.
Since 23 and 16102996 are co-prime, the answer is 0.

Naive Approach: The simplest approach is to check all possible indexes of partition from the start of the array and check if the product of the subarrays formed is co-prime or not. If there exists any such index then print that index. Otherwise, print “-1”
Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to use the prefix product array and suffix product array and find the possible index. Follow the steps below to solve the problem:



  • Create two auxiliary arrays, prefix[] and suffix[] to store the prefix and suffix array product. Initialize prefix[0] to arr[0] and suffix[N – 1] to arr[N – 1].
  • Traverse the given array over the range [2, N] using variable i and update the prefix array as prefix[i] = prefix[i – 1]*arr[i].
  • Traverse the given array from the back over the range [N – 2, 0] using variable i and update the suffix array as suffix[i] = suffix[i + 1]*arr[i].
  • Iterate a loop over the range [0, N – 1] using variable i and check if prefix[i] and suffix[i + 1] are co-prime or not. If found to be true the print the current index and break out of the loop.
  • If there doesn’t exist any such index in the above step then print “-1”.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the GCD of 2 numbers
int GCD(int a, int b)
{
    // Base Case
    if (b == 0)
        return a;
 
    // Find the GCD recursively
    return GCD(b, a % b);
}
 
// Function to find the minimum partition
// index K s.t. product of both subarrays
// around that partition are co-prime
int findPartition(int nums[], int N)
{
 
    // Stores the prefix and suffix
    // array product
    int prefix[N], suffix[N], i, k;
 
    prefix[0] = nums[0];
 
    // Update the prefix array
    for (i = 1; i < N; i++) {
        prefix[i] = prefix[i - 1]
                    * nums[i];
    }
 
    suffix[N - 1] = nums[N - 1];
 
    // Update the suffix array
    for (i = N - 2; i >= 0; i--) {
        suffix[i] = suffix[i + 1]
                    * nums[i];
    }
 
    // Iterate the given array
    for (k = 0; k < N - 1; k++) {
        // Check if prefix[k] and
        // suffix[k+1] are co-prime
        if (GCD(prefix[k],
                suffix[k + 1])
            == 1) {
            return k;
        }
    }
 
    // If no index for partition
    // exists, then return -1
    return -1;
}
 
// Driver Code
int main()
{
 
    int arr[] = { 2, 3, 4, 5 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << findPartition(arr, N);
 
    return 0;
}

Java




// Java program for the
// above approach
import java.util.*;
class solution{
    
// Function to find the
// GCD of 2 numbers
static int GCD(int a,
               int b)
{
  // Base Case
  if (b == 0)
    return a;
 
  // Find the GCD
  // recursively
  return GCD(b, a % b);
}
 
// Function to find the minimum
// partition index K s.t. product
// of both subarrays around that
// partition are co-prime
static int findPartition(int nums[],
                         int N)
{
  // Stores the prefix and
  // suffix array product
  int []prefix = new int[N];
  int []suffix = new int[N];
  int i, k;
 
  prefix[0] = nums[0];
 
  // Update the prefix array
  for (i = 1; i < N; i++)
  {
    prefix[i] = prefix[i - 1] *
                nums[i];
  }
 
  suffix[N - 1] = nums[N - 1];
 
  // Update the suffix array
  for (i = N - 2; i >= 0; i--)
  {
    suffix[i] = suffix[i + 1] *
                nums[i];
  }
 
  // Iterate the given array
  for (k = 0; k < N - 1; k++)
  {
    // Check if prefix[k] and
    // suffix[k+1] are co-prime
    if (GCD(prefix[k],
            suffix[k + 1]) == 1)
    {
      return k;
    }
  }
 
  // If no index for partition
  // exists, then return -1
  return -1;
}
 
// Driver Code
public static void main(String args[])
{
  int arr[] = {2, 3, 4, 5};
  int N = arr.length;
 
  // Function call
  System.out.println(findPartition(arr, N));
}
}
 
// This code is contributed by SURENDRA_GANGWAR

Python3




# Python3 program for the
# above approach
 
# Function to find the
# GCD of 2 numbers
def GCD(a, b):
   
    # Base Case
    if (b == 0):
        return a
 
    # Find the GCD recursively
    return GCD(b, a % b)
 
# Function to find the minimum
# partition index K s.t. product
# of both subarrays around that
# partition are co-prime
def findPartition(nums, N):
 
    #Stores the prefix and
    # suffix array product
    prefix=[0] * N
    suffix=[0] * N
 
    prefix[0] = nums[0]
 
    # Update the prefix
    # array
    for i in range(1, N):
        prefix[i] = (prefix[i - 1] *
                     nums[i])
 
    suffix[N - 1] = nums[N - 1]
 
    # Update the suffix array
    for i in range(N - 2, -1, -1):
        suffix[i] = (suffix[i + 1] *
                     nums[i])
 
    # Iterate the given array
    for k in range(N - 1):
       
        # Check if prefix[k] and
        # suffix[k+1] are co-prime
        if (GCD(prefix[k],
                suffix[k + 1]) == 1):
            return k
 
    # If no index for partition
    # exists, then return -1
    return -1
 
# Driver Code
if __name__ == '__main__':
   
    arr = [2, 3, 4, 5]
    N = len(arr)
 
    # Function call
    print(findPartition(arr, N))
 
# This code is contributed by Mohit Kumar 29

C#




// C# program for the
// above approach
using System;
class GFG{
     
// Function to find the
// GCD of 2 numbers
static int GCD(int a, int b)
{
  // Base Case
  if (b == 0)
    return a;
 
  // Find the GCD
  // recursively
  return GCD(b, a % b);
}
 
// Function to find the minimum
// partition index K s.t. product
// of both subarrays around that
// partition are co-prime
static int findPartition(int[] nums,
                         int N)
{
  // Stores the prefix and
  // suffix array product
  int[] prefix = new int[N];
  int[] suffix = new int[N];
  int i, k;
 
  prefix[0] = nums[0];
 
  // Update the prefix array
  for (i = 1; i < N; i++)
  {
    prefix[i] = prefix[i - 1] *
                nums[i];
  }
 
  suffix[N - 1] = nums[N - 1];
 
  // Update the suffix array
  for (i = N - 2; i >= 0; i--)
  {
    suffix[i] = suffix[i + 1] *
                nums[i];
  }
 
  // Iterate the given array
  for (k = 0; k < N - 1; k++)
  {
    // Check if prefix[k] and
    // suffix[k+1] are co-prime
    if (GCD(prefix[k],
            suffix[k + 1]) == 1)
    {
      return k;
    }
  }
 
  // If no index for partition
  // exists, then return -1
  return -1;
}
 
// Driver code
static void Main()
{
  int[] arr = {2, 3, 4, 5};
  int N = arr.Length;
 
  // Function call
  Console.WriteLine(findPartition(arr, N));
}
}
 
// This code is contributed by divyeshrabadiya07

Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to find the GCD of 2 numbers
function GCD(a, b)
{
    // Base Case
    if (b == 0)
        return a;
 
    // Find the GCD recursively
    return GCD(b, a % b);
}
 
// Function to find the minimum partition
// index K s.t. product of both subarrays
// around that partition are co-prime
function findPartition(nums, N)
{
 
    // Stores the prefix and suffix
    // array product
    var prefix = Array(N), suffix = Array(N), i, k;
 
    prefix[0] = nums[0];
 
    // Update the prefix array
    for (i = 1; i < N; i++) {
        prefix[i] = prefix[i - 1]
                    * nums[i];
    }
 
    suffix[N - 1] = nums[N - 1];
 
    // Update the suffix array
    for (i = N - 2; i >= 0; i--) {
        suffix[i] = suffix[i + 1]
                    * nums[i];
    }
 
    // Iterate the given array
    for (k = 0; k < N - 1; k++) {
        // Check if prefix[k] and
        // suffix[k+1] are co-prime
        if (GCD(prefix[k],
                suffix[k + 1])
            == 1) {
            return k;
        }
    }
 
    // If no index for partition
    // exists, then return -1
    return -1;
}
 
// Driver Code
var arr = [2, 3, 4, 5];
var N = arr.length;
// Function call
document.write( findPartition(arr, N));
 
</script>
Output: 
2

 

Time Complexity: O(N log(N))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :