Rearrange array to obtain maximum possible value of concatenation of prefix GCDs

Given an array arr[] consisting of N positive integers, the task is to rearrange the array elements such that the number formed by concatenating the GCD of elements of the array arr[] from index 0 to i for each index i is the maximum possible.
Examples:
Input: arr[] = {4, 2, 5}
Output: 5 4 2
Explanation:
X = 511 is the maximum value of X that can be obtained among all the rearrangement of arr[].
Possible arrangements of arr[] are:
arr[] = [2, 4, 5] ? X = 221
arr[] = [2, 5, 4] ? X = 211
arr[] = [4, 2, 5] ? X = 421
arr[] = [4, 5, 2] ? X = 411
arr[] = [5, 4, 2] ? X = 511
arr[] = [5, 2, 4] ? X = 511Input: arr[] = {2, 4, 6, 8}
Output: 8 4 6 2
Explanation:Â
X = 842 is the maximum value of X that can be obtained among all the rearrangement of arr[].
Possible arrangements of arr[] are:
arr[] = [4, 6, 8] ? X = 422
arr[] = [4, 8, 6] ? X = 442
arr[] = [6, 4, 8] ? X = 622
arr[] = [6, 8, 4] ? X = 622
arr[] = [8, 4, 6] ? X = 842
arr[] = [8, 6, 4] ? X = 822
Approach: The GCD of a number alone is the number itself, thus the first digit of X i.e., X[0] would always be equal to arr[0]. Thus, to ensure that X is maximum among all obtainable numbers, arr[0] needs to be maximum. Then proceed by keeping track of the GCD of the longest prefix of arr[] that has been already arranged and find the values of the consecutive elements to be placed after this prefix. Follow the steps below to solve the above problem:
- The largest element of the array is set as the first element, thus the first prefix correctly arranged in the array arr[].
- Now find the element consecutive to the last element of the prefix i.e., arr[1].
- Here the GCD of the longest prefix(say G) is equal to arr[0], thus traverse the remaining array to find the element that gives the greatest GCD with G.
- Now, swap the element arr[1] with the element that gives maximum GCD with value G, update the value of G to this maximum GCD obtained i.e., G = GCD(G, arr[1]).
- Now the longest fixed prefix becomes arr[0], arr[1], continue this process for finding arr[2], arr[3], …, arr[N – 1], to obtain the required array.
- Print rearrange array after the above steps.
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 maximum number// obtainable from prefix GCDsvoid prefixGCD(int arr[], int N){    // Stores the GCD of the    // longest prefix    int gcc;Â
    // Sort the array    sort(arr, arr + N);Â
    // Reverse the array    reverse(arr, arr + N);Â
    // GCD of a[0] is a[0]    gcc = arr[0];    int start = 0;Â
    // Iterate to place the arr[start + 1]    // element at it's correct position    while (start < N - 1) {Â
        int g = 0, s1;Â
        for (int i = start + 1; i < N; i++) {Â
            // Find the element with            // maximum GCD            int gc = __gcd(gcc, arr[i]);Â
            // Update the value of g            if (gc > g) {                g = gc;                s1 = i;            }        }Â
        // Update GCD of prefix        gcc = g;Â
        // Place arr[s1] to it's        // correct position        swap(arr[s1], arr[start + 1]);Â
        // Increment start for the        // remaining elements        start++;    }Â
    // Print the rearranged array    for (int i = 0; i < N; i++) {        cout << arr[i] << " ";    }}Â
// Driver Codeint main(){Â Â Â Â // Given array arr[]Â Â Â Â int arr[] = { 1, 2, 3, 4 };Â
    int N = sizeof(arr) / sizeof(arr[0]);Â
    // Function Call    prefixGCD(arr, N);Â
    return 0;} |
Java
//Java program for // the above approachimport java.util.*;class GFG{Â
//Function to find the maximum number//obtainable from prefix GCDsstatic void prefixGCD(int arr[], int N){  // Stores the GCD of the  // longest prefix  int gcc;Â
  // Sort the array  Arrays.sort(arr);Â
  // Reverse the array  arr = reverse(arr);Â
  // GCD of a[0] is a[0]  gcc = arr[0];  int start = 0;Â
  // Iterate to place  // the arr[start + 1]  // element at it's   // correct position  while (start < N - 1)   {    int g = 0, s1 = 0;Â
    for (int i = start + 1; i < N; i++)     {      // Find the element with      // maximum GCD      int gc = __gcd(gcc, arr[i]);Â
      // Update the value of g      if (gc > g)       {        g = gc;        s1 = i;      }    }Â
    // Update GCD of prefix    gcc = g;Â
    // Place arr[s1] to it's    // correct position    arr = swap(arr, s1, start + 1);Â
    // Increment start for the    // remaining elements    start++;  }Â
  // Print the rearranged array  for (int i = 0; i < N; i++)   {    System.out.print(arr[i] + " ");  } }   static int __gcd(int a, int b) {   return b == 0 ? a : __gcd(b, a % b);    }Â
static int[] reverse(int a[]) {Â Â int i, n = a.length, t;Â Â for (i = 0; i < n / 2; i++) Â Â {Â Â Â Â t = a[i];Â Â Â Â a[i] = a[n - i - 1];Â Â Â Â a[n - i - 1] = t;Â Â }Â Â return a;}Â
static int[] swap(int []arr, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int i, int j){Â Â int temp = arr[i];Â Â arr[i] = arr[j];Â Â arr[j] = temp;Â Â return arr;}Â Â Â Â Â //Driver Codepublic static void main(String[] args){Â Â // Given array arr[]Â Â int arr[] = {1, 2, 3, 4};Â
  int N = arr.length;Â
  // Function Call  prefixGCD(arr, N);}}Â
//This code is contributed by 29AjayKumar |
Python3
# Python3 program for the above approachfrom math import gcdÂ
# Function to find the maximum number# obtainable from prefix GCDsdef prefixGCD(arr, N):         # Stores the GCD of the    # longest prefix    gcc = 0Â
    # Sort the array    arr = sorted(arr)Â
    # Reverse the array    arr = arr[::-1]Â
    # GCD of a[0] is a[0]    gcc = arr[0]    start = 0Â
    # Iterate to place the arr[start + 1]    # element at it's correct position    while (start < N - 1):        g = 0        s1 = 0Â
        for i in range(start + 1, N):Â
            # Find the element with            # maximum GCD            gc = gcd(gcc, arr[i])Â
            # Update the value of g            if (gc > g):                g = gc                s1 = iÂ
        # Update GCD of prefix        gcc = gÂ
        # Place arr[s1] to it's        # correct position        arr[s1], arr[start + 1] = arr[start + 1], arr[s1]Â
        # Increment start for the        # remaining elements        start += 1Â
    # Print the rearranged array    for i in range(N):        print(arr[i], end = " ")Â
# Driver Codeif __name__ == '__main__':Â Â Â Â Â Â Â Â Â # Given array arr[]Â Â Â Â arr = [ 1, 2, 3, 4 ]Â
    N = len(arr)Â
    # Function Call    prefixGCD(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 maximum number// obtainable from prefix GCDsstatic void prefixGCD(int[] arr, int N){       // Stores the GCD of the  // longest prefix  int gcc;Â
  // Sort the array  Array.Sort(arr);Â
  // Reverse the array  arr = reverse(arr);Â
  // GCD of a[0] is a[0]  gcc = arr[0];  int start = 0;Â
  // Iterate to place the   // arr[start + 1] element  // at it's correct position  while (start < N - 1)   {    int g = 0, s1 = 0;Â
    for(int i = start + 1; i < N; i++)     {               // Find the element with      // maximum GCD      int gc = __gcd(gcc, arr[i]);Â
      // Update the value of g      if (gc > g)       {        g = gc;        s1 = i;      }    }Â
    // Update GCD of prefix    gcc = g;Â
    // Place arr[s1] to it's    // correct position    arr = swap(arr, s1, start + 1);Â
    // Increment start for the    // remaining elements    start++;  }Â
  // Print the rearranged array  for(int i = 0; i < N; i++)   {    Console.Write(arr[i] + " ");  } }   static int __gcd(int a, int b) {   return b == 0 ? a : __gcd(b, a % b);    }Â
static int[] reverse(int[] a) {Â Â int i, n = a.Length, t;Â Â Â Â Â for(i = 0; i < n / 2; i++) Â Â {Â Â Â Â t = a[i];Â Â Â Â a[i] = a[n - i - 1];Â Â Â Â a[n - i - 1] = t;Â Â }Â Â return a;}Â
static int[] swap(int []arr, int i, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int j){Â Â int temp = arr[i];Â Â arr[i] = arr[j];Â Â arr[j] = temp;Â Â return arr;}Â Â Â Â Â //Driver Codepublic static void Main(){Â Â Â Â Â Â Â // Given array arr[]Â Â int[] arr = { 1, 2, 3, 4 };Â
  int N = arr.Length;Â
  // Function call  prefixGCD(arr, N);}}Â
// This code is contributed by sanjoy_62 |
Javascript
<script>Â
// Javascript program to implement// the above approachÂ
//Function to find the maximum number//obtainable from prefix GCDsfunction prefixGCD(arr, N){  // Stores the GCD of the  // longest prefix  let gcc;Â
  // Sort the array  arr.sort();Â
  // Reverse the array  arr = reverse(arr);Â
  // GCD of a[0] is a[0]  gcc = arr[0];  let start = 0;Â
  // Iterate to place  // the arr[start + 1]  // element at it's   // correct position  while (start < N - 1)   {    let g = 0, s1 = 0;Â
    for (let i = start + 1; i < N; i++)     {      // Find the element with      // maximum GCD      let gc = __gcd(gcc, arr[i]);Â
      // Update the value of g      if (gc > g)       {        g = gc;        s1 = i;      }    }Â
    // Update GCD of prefix    gcc = g;Â
    // Place arr[s1] to it's    // correct position    arr = swap(arr, s1, start + 1);Â
    // Increment start for the    // remaining elements    start++;  }Â
  // Print the rearranged array  for (let i = 0; i < N; i++)   {    document.write(arr[i] + " ");  } }   function __gcd(a, b) {   return b == 0 ? a : __gcd(b, a % b);    }Â
function reverse(a) {Â Â let i, n = a.length, t;Â Â for (i = 0; i < n / 2; i++) Â Â {Â Â Â Â t = a[i];Â Â Â Â a[i] = a[n - i - 1];Â Â Â Â a[n - i - 1] = t;Â Â }Â Â return a;}Â
function swap(arr, i, j){Â Â let temp = arr[i];Â Â arr[i] = arr[j];Â Â arr[j] = temp;Â Â return arr;}Â
// Driver CodeÂ
    // Given array arr[]  let arr = [1, 2, 3, 4];Â
  let N = arr.length;Â
  // Function Call  prefixGCD(arr, N);Â
</script> |
4 2 3 1
Â
Time Complexity: O(N2)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



