# Find permutation which generates lexicographically largest Array of GCD of Prefixes

• Last Updated : 05 Sep, 2022

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 ``using` `namespace` `std;` `pair, vector<``int``> >``Findpermutation(vector<``int``>& A)``{``    ``// We use this to save all possible result``    ``// from every permutations``    ``vector, 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() 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``> > 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 ``using` `namespace` `std;` `// Function to  find the permutation``pair, 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``> > 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