Skip to content
Related Articles

Related Articles

Find permutation which generates lexicographically largest Array of GCD of Prefixes

View Discussion
Improve Article
Save Article
  • Last Updated : 05 Sep, 2022
View Discussion
Improve Article
Save Article

Given an array A[] of size N, find the permutation of array A such that the array B[] which is formed by taking the GCD of the prefixes of array A is lexicographically greatest among all possible arrays. Print the permutation of A and also B. 

Note: If multiple answers are possible, print any of them

Examples:

Input: A[] = {2, 1, 4, 8, 16, 32, 5}
Output: A[] = {32, 16, 8, 4, 2, 5, 1}, B = {32, 16, 8, 4, 2, 1, 1}
Explanation: B[] = {gcd(32),  gcd(32, 16),  gcd(32, 16, 8), gcd(32, 16, 8, 4),  
gcd(32, 16, 8, 4, 2), gcd(32, 16, 8, 4, 2, 1, 5), gcd(32, 16, 8, 4, 2, 1, 5)}  

Input: A[] =  {5, 20, 21, 5, 17}
Output: A[] = {21, 20, 17, 5, 5 }, B[] = {21, 1, 1, 1, 1}

Naive Approach: 

Iterate through all the permutations of A, find the gcd of the prefix of the array then sort all the arrays and print the greatest lexicographically array of gcd of the prefix.

Follow the steps mentioned below to implement the idea:

  • Generate the permutation for the array.
    • Iterate through the array and generate the B[] array from that permutation.
    • Check if it is the lexicographically greatest and update accordingly.
  • Return the permutation which generates the lexicographically largest B[].

Below is the code for the above-mentioned approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
pair<vector<int>, vector<int> >
Findpermutation(vector<int>& A)
{
    // We use this to save all possible result
    // from every permutations
    vector<pair<vector<int>, vector<int> > > sv;
    sort(A.begin(), A.end());
 
    // This section used c++ stl to go through all
    // permutations of array A, but before that it needs to
    // be sorted, that's why we sorted above.
    do {
        int x = 0;
 
        // Find the gcd of prefix of array
        // for this permutation
        vector<int> B;
 
        // Go through elements of A
        // in this particular permutation
        for (int i = 0; i < A.size(); i++) {
            x = __gcd(x, A[i]);
            B.push_back(x);
        }
 
        // The above logic is building B for this
        // permutation of A by using logic that
        // gcd(prefix[i]) = gcd(prefix[i-1], A[i]) for any i
        // and the initial value is taken as 0 because
        // GCD(0, A[i]) = A[i]
        sv.push_back({ B, A });
 
        // Add this B into our all results.
    } while (next_permutation(A.begin(), A.end()));
 
    // We sort the results to find the best result, notice
    // we used greater<vector<int>() as sorting function
    sort(sv.begin(), sv.end());
 
    // Return the first result because this is
    // lexicographically greatest.
    return sv.back();
}
 
// Driver Code
int main()
{
 
    // This is the input array A
    vector<int> A = { 2, 1, 4, 8, 16, 32, 5 };
 
    // Function call
    pair<vector<int>, vector<int> > result
        = Findpermutation(A);
    cout << "A = ";
    for (int i : result.second) {
        cout << i << ' ';
    }
    cout << endl;
 
    cout << "B = ";
    for (int i : result.first) {
        cout << i << ' ';
    }
    return 0;
}

Output

A = 32 16 8 4 2 5 1 
B = 32 16 8 4 2 1 1 

Time Complexity: O(N * N!), N! to find the permutation and N to iterate on each permutations.
Auxiliary Space: O(1)

Efficient Approach: 

Iterate all the elements and for each element:

  • Traverse  all the other elements and find which element gives the greatest GCD among them.
  • That will the be next element because it will generate a greater GCD for the B[] array. 

Continue this process till the array is built.

Follow the steps mentioned below to implement the idea:

  • Initially store a GCD = 0 (to get the max gcd in next step, because gcd(0, x) = x)
  • Traverse from i = 0 to N:
    • Iterate from j = 0 to N.
      • If the gcd of A[j] with the previous gcd is maximum update the gcd value.
    • Put A[j] and the maximum GCD in the resultant arrays.
  • When the iteration is over, return the resultant arrays.

Below is the implementation for the above approach

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to  find the permutation
pair<vector<int>, vector<int> >
Findpermutation(vector<int>& A)
{
    // This array to mark the elements
    // as used so we don't use again.
    vector<bool> used(A.size(), 0);
 
    // This will save or result
    vector<int> ansA;
    vector<int> ansB;
 
    int x = 0;
 
    for (int i = 0; i < A.size(); i++) {
 
        // This code segment finds
        // the next best element for
        // max gcd of prefix
        int temp = 0, mx_gcd = 0, index = -1;
 
        // We start with temp, mx_gcd as 0
        // because of gcd property
        // GCD(0, x) = x
        for (int j = 0; j < A.size(); j++) {
 
            if (!used[j]) {
 
                // We are taking gcd with x
                temp = __gcd(x, A[j]);
 
                // If this gcd is better than before
                // then take this as new index.
                if (temp > mx_gcd) {
                    mx_gcd = temp;
                    index = j;
                }
            }
        }
 
        // Take the new best gcd and
        // merge with the previous result
        x = __gcd(x, mx_gcd);
 
        // Mark the element as used
        used[index] = 1;
 
        // Add the element to answer
        ansB.push_back(x);
        ansA.push_back(A[index]);
    }
    return { ansA, ansB };
}
 
// Driver Code
int main()
{
    vector<int> A = { 2, 1, 4, 8, 16, 32, 5 };
 
    // Function call
    pair<vector<int>, vector<int> > ans
        = Findpermutation(A);
    cout << "A = ";
    for (int i : ans.first) {
        cout << i << ' ';
    }
    cout << endl;
 
    cout << "B = ";
    for (int i : ans.second) {
        cout << i << ' ';
    }
    return 0;
}

Output

A = 32 16 8 4 2 1 5 
B = 32 16 8 4 2 1 1 

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


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!