Subsequence of size k with maximum possible GCD


The problem statement says we will be given an array as input and a positive integer K, we need to figure out the maximum possible gcd(greatest common divisor) of a ksized subsequence of an array in this problem. It can be solved using different algorithms to find gcd of the numbers and figuring out the maximum gcd for a k-sized subsequence.

Before that we must know about the subsequence of an array. A subsequence of an array is a sequence of numbers from the array not necessarily adjacent numbers in the array but the order of the numbers in the sequence must be the same as they are in the array to be called a subsequence of an array. A subsequence may or may not be contiguous in nature.

For example, a=[1,2,3,4,5,6]. [1, 2, 5] is a subsequence of an array a. In this problem, we need to find out the right subsequence of size K, of the array a[] such that the greatest common divisor of the subsequence is the maximum possible gcd among all the subsequence of size K. The problem can be better understood with these examples −

INPUT : a=[5, 2, 6, 10, 12] , K=2

OUTPUT : 6

Explanation : 6 is the maximum possible gcd of subsequence of size K i.e. 2. 6 is gcd of [6,12]. There could be other subsequences too like [5,10], [10,12], and many more. But the gcd of [5,10] is 5 and [10,12] is 2. Thus 6 is the maximum possible gcd among all the subsequences of size 2.

INPUT : a=[1,2,3,4,5] , K=3

OUTPUT : 1

Explanation : The size of the subsequence given is 3. Any possible subsequence of size 3 has only 1 as their greatest common divisor. Thus, 1 is our output.

Let’s look at the algorithm that we can use to solve this problem.

Algorithm

The naive approach to solve this issue can be generating all possible k-sized subsequences and then calculating gcd of each of them. The greatest common divisor found among all the calculated gcd will be our answer. Since the algorithm will only work for small arrays, we cannot use it as our approach to solve the problem.

The efficient approach to solve this problem can be −

  • We will create an array of size equals to the maximum element present in the array+1.

  • We can find the maximum element present in the array using *max_element() function inbuilt in C++ which returns the maximum element in the given range.

Syntax

int x= *max_element(arr, arr+n); //n is the size of the array
  • We will iterate in a for loop in the given array from i=0 to i=array.size() to calculate the number of divisors of every element present in the array.

  • Iterating in a nested for loop from j=1 to sqrt(a[i]) because in mathematics every number which has two factors has one factor less than the square root of that number.

  • If j divides the number a[i], then update the value in the array we created at jth index by adding 1 to it. Then also update the value at (a[i]/j)th index of the array by 1 if it is not equal to j because if j divides a[i] to give some number then that number will also be the divisor of a[i] (a[i]/j=x or a[i]/x=j).

  • Finally after iterating all the elements in the given array, we will then iterate in the array that we created and store the values in. Iterating in the array from the last element and checking if the value at that index is greater than or equal to K.

  • If the value at any index is greater than or equal to K while iterating from last, that index will be our required answer because every number at any index in the array represents the number of elements the index value divides in the given array. So iterating from last will give us the maximum possible number that divides K or more numbers in the given array.

Let us now implement this algorithm in our approach to solve the problem.

Approach

The steps that we are going to follow to solve the above problem −

  • Initialize a function to calculate maximum possible gcd of subsequence of size K.

  • Store the maximum element of the array given in a variable m.

  • Create an array of size m+1, count[m+1].

  • Iterate in a for loop from i=0 to size of the array.

  • In a nested for loop, iterate from j=1 to sqrt(a[i]) and check for every value of j that if it divides a[i].

  • If it divides, increase the value at jth index of count by 1. Also check if j is not equal to (a[i]/j), then increase the value at (a[i]/j)th index also by 1.

  • Then after all the iterations again iterate in count after updating all the required values.

  • Iterate in count from last until i is greater than or equal to 1 because 0 doesn’t divide any number. The first index we come across whose value is greater than or equal to K, the index value will be our answer.

  • Return that index as output.

Example

The implementation of the approach in C++ −

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//function to calculate maximum gcd possible of subsequence of size K
int maximum_gcd(int a[], int N, int K){
   int m = *max_element(a,a+N); //store maximum element present in the array
   int count[m+1]={0}; //create an array to store count of every divisor
   for(int i=0;i<N;i++){ //iterate in the given array
      for(int j=1;j<=sqrt(a[i]);j++){ //to get every possible divisor of the given number in the array
         if(a[i]%j==0){
            //if it is a divisor of the number, update the count
            count[j]=count[j]+1;
            if(a[i]/j != j){ //a[i]/j is also the divisor of the number if j divides a[i]
               count[a[i]/j] = count[a[i]/j] + 1;
            }
         }
      }
   }
   int ans; //to store maximum gcd of subsequence of size K
   for(int i=m;i>=1;--i){ //iterating from to get the maximum value
      if(count[i]>=K){ //if value at index is greater than or equal to K
         ans = i; //the index must be the gcd of atleast one K-sized subsequence
         break;
      }
   }
   return ans; //return the answer
}
int main(){
   int a[]={8,10,3,15,20,9};
   int K=3;
   int N = sizeof(a)/sizeof(a[0]); //to calculate the size of the given array
   cout<<maximum_gcd(a,N,K)<<endl;
   return 0;
}

Output

5

Time Complexity: O(𝑁 × 𝑠𝑞𝑟𝑡(𝑚) ), where N is the size of the given array and m is the maximum element present in the array.

Space Complexity: O(m+1), where m is the maximum element present in the given array.

Conclusion

We have discussed solving the problem to find the maximum possible gcd(greatest common divisor) of a subsequence of size K in C++ using different functions and methods. From the naive approach to the efficient approach, we discussed how we can solve the above problem i C++.

I hope you find this article helpful to solve your concept about the problem.

Updated on: 16-Mar-2023

517 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements