# Maximize GCD of an array by increments or decrements by K

• Last Updated : 06 May, 2021

Given an array arr[] consisting of N positive integers and a positive integer K, the task is to maximize the GCD of the array arr[] by either increasing or decreasing any array element by K.

Examples:

Input: arr[] = {3, 9, 15, 24}, K = 1
Output: 4
Explanation:
Perform the following operations on the array arr[]:
Increment arr[0] by 1. Therefore, arr[] modifies to {4, 9, 15, 24}.
Decrement arr[1] by 1. Therefore, arr[] modifies to {4, 8, 15, 24}.
Increment arr[2] by 1. Therefore, arr[] modifies to {4, 8, 16, 24}.
Therefore, GCD of the modified array is 4.

Input: arr[] = {5, 9, 2}, K = 1
Output: 3

Naive Approach: The simplest approach to solve this problem is to consider all three options for each array element arr[i], i.e., increase arr[i] by K, decrease arr[i] by K or neither increment nor decrement arr[i]. Generate the arrays formed in all the 3 cases using recursion and print the maximum of GCD of all the arrays obtained.

Time Complexity: O(3N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized using Dynamic Programming. Follow the steps below to solve the given problem:

• Initialize an auxiliary array, say dp[][3], where dp[i][0], dp[i][1], and dp[i][2] denotes the maximum GCD possible upto ith index by not changing the ith elements, incrementing or decrementing the ith element by K respectively.
• Fill the first row of dp[][3] by updating dp[0][0], dp[0][1] and dp[0][2] with arr[0], arr[0] + K and arr[0] – K respectively.
• Iterate over the range [1, N – 1] and perform the following steps:
• For dp[i][0], find the maximum GCD of A[i] with 3 previous states, i.e., dp[i – 1][0], dp[i – 1][1] and dp[i – 1][2] once at a time, and store the maximum result in dp[i][0].
• Similarly, store the results in dp[i][1] and dp[i][2] by taking (arr[i] + K) and (arr[i] – K) respectively.
• After completing the above steps, print the maximum value in the row dp[N – 1] as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to return the maximum GCD``// by taking each operation``int` `findGCD(``int` `x, ``int` `y, ``int` `z, ``int` `res)``{``    ``// Store the maximum GCD obtained``    ``// by either incrementing, decrementing``    ``// or not changing A[i]``    ``int` `ans = __gcd(x, res);``    ``ans = max(ans, __gcd(y, res));``    ``ans = max(ans, __gcd(z, res));` `    ``// Return the maximum GCD``    ``return` `ans;``}` `// Function to find the maximum GCD of``// the array arrA[] by either increasing``// or decreasing the array elements by K``int` `maximumGCD(``int` `A[], ``int` `N, ``int` `K)``{``    ``// Initialize a dp table of size N*3``    ``int` `dp[N][3];``    ``memset``(dp, 0, ``sizeof``(dp));` `    ``// Base Cases:``    ``// If only one element is present``    ``dp[0][0] = A[0];``    ``dp[0][1] = A[0] + K;``    ``dp[0][2] = A[0] - K;` `    ``// Traverse the array A[] over indices [1, N - 1]``    ``for` `(``int` `i = 1; i < N; i++) {` `        ``// Store the previous state results``        ``int` `x = dp[i - 1][0];``        ``int` `y = dp[i - 1][1];``        ``int` `z = dp[i - 1][2];` `        ``// Store maximum GCD result``        ``// for each current state``        ``dp[i][0] = findGCD(x, y, z, A[i]);``        ``dp[i][1] = findGCD(x, y, z, A[i] + K);``        ``dp[i][2] = findGCD(x, y, z, A[i] - K);``    ``}` `    ``// Store the required result``    ``int` `mx = max(``        ``{ 3, dp[N - 1][0], dp[N - 1][1],``          ``dp[N - 1][2] });` `    ``// Return the result``    ``return` `mx;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 3, 9, 15, 24 };``    ``int` `K = 1;``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``cout << maximumGCD(arr, N, K);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.io.*;``import` `java.util.*;``class` `GFG``{` `  ``// Recursive function to return gcd of a and b``  ``static` `int` `gcd(``int` `a, ``int` `b)``  ``{``    ``// Everything divides 0``    ``if` `(a == ``0``)``      ``return` `b;``    ``if` `(b == ``0``)``      ``return` `a;` `    ``// base case``    ``if` `(a == b)``      ``return` `a;` `    ``// a is greater``    ``if` `(a > b)``      ``return` `gcd(a-b, b);``    ``return` `gcd(a, b-a);``  ``}` `  ``// Function to return the maximum GCD``  ``// by taking each operation``  ``static` `int` `findGCD(``int` `x, ``int` `y, ``int` `z, ``int` `res)``  ``{``    ``// Store the maximum GCD obtained``    ``// by either incrementing, decrementing``    ``// or not changing A[i]``    ``int` `ans = gcd(x, res);``    ``ans = Math.max(ans, gcd(y, res));``    ``ans = Math.max(ans, gcd(z, res));` `    ``// Return the maximum GCD``    ``return` `ans;``  ``}` `  ``// Function to find the maximum GCD of``  ``// the array arrA[] by either increasing``  ``// or decreasing the array elements by K``  ``static` `int` `maximumGCD(``int` `A[], ``int` `N, ``int` `K)``  ``{``    ``// Initialize a dp table of size N*3``    ``int` `dp[][] = ``new` `int``[N][``3``];``    ``for` `(``int` `i = ``0``; i < N; i++) {``      ``for` `(``int` `j = ``1``; j < ``3``; j++) {``        ``dp[i][j] = ``0``;``      ``}``    ``}` `    ``// Base Cases:``    ``// If only one element is present``    ``dp[``0``][``0``] = A[``0``];``    ``dp[``0``][``1``] = A[``0``] + K;``    ``dp[``0``][``2``] = A[``0``] - K;` `    ``// Traverse the array A[] over indices [1, N - 1]``    ``for` `(``int` `i = ``1``; i < N; i++) {` `      ``// Store the previous state results``      ``int` `x = dp[i - ``1``][``0``];``      ``int` `y = dp[i - ``1``][``1``];``      ``int` `z = dp[i - ``1``][``2``];` `      ``// Store maximum GCD result``      ``// for each current state``      ``dp[i][``0``] = findGCD(x, y, z, A[i]);``      ``dp[i][``1``] = findGCD(x, y, z, A[i] + K);``      ``dp[i][``2``] = findGCD(x, y, z, A[i] - K);``    ``}` `    ``// Store the required result``    ``int` `mx = Math.max(``3``, Math.max(dp[N - ``1``][``0``], Math.max(dp[N - ``1``][``1``],``                                                         ``dp[N - ``1``][``2``])));` `    ``// Return the result``    ``return` `mx;``  ``}`  `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `arr[] = { ``3``, ``9``, ``15``, ``24` `};``    ``int` `K = ``1``;``    ``int` `N = arr.length;` `    ``System.out.print( maximumGCD(arr, N, K));``  ``}``}` `// This code is contributed by sanjoy_62.`

## Python3

 `# Python3 program for the above approach``import` `math` `# Function to return the maximum GCD``# by taking each operation``def` `findGCD(x, y, z, res):``    ` `    ``# Store the maximum GCD obtained``    ``# by either incrementing, decrementing``    ``# or not changing A[i]``    ``ans ``=` `math.gcd(x, res)``    ``ans ``=` `max``(ans, math.gcd(y, res))``    ``ans ``=` `max``(ans, math.gcd(z, res))` `    ``# Return the maximum GCD``    ``return` `ans` `# Function to find the maximum GCD of``# the array arrA[] by either increasing``# or decreasing the array elements by K``def` `maximumGCD(A, N, K):``    ` `    ``# Initialize a dp table of size N*3``    ``dp ``=` `[[``0` `for` `x ``in` `range``(``3``)]``             ``for` `y ``in` `range``(N)]` `    ``# Base Cases:``    ``# If only one element is present``    ``dp[``0``][``0``] ``=` `A[``0``]``    ``dp[``0``][``1``] ``=` `A[``0``] ``+` `K``    ``dp[``0``][``2``] ``=` `A[``0``] ``-` `K` `    ``# Traverse the array A[] over``    ``# indices [1, N - 1]``    ``for` `i ``in` `range``(``1``, N):``        ` `        ``# Store the previous state results``        ``x ``=` `dp[i ``-` `1``][``0``]``        ``y ``=` `dp[i ``-` `1``][``1``]``        ``z ``=` `dp[i ``-` `1``][``2``]` `        ``# Store maximum GCD result``        ``# for each current state``        ``dp[i][``0``] ``=` `findGCD(x, y, z, A[i])``        ``dp[i][``1``] ``=` `findGCD(x, y, z, A[i] ``+` `K)``        ``dp[i][``2``] ``=` `findGCD(x, y, z, A[i] ``-` `K)` `    ``# Store the required result``    ``mx ``=` `max``([``3``, dp[N ``-` `1``][``0``],``                 ``dp[N ``-` `1``][``1``],``                 ``dp[N ``-` `1``][``2``]])` `    ``# Return the result``    ``return` `mx` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``arr ``=` `[ ``3``, ``9``, ``15``, ``24` `]``    ``K ``=` `1``    ``N ``=` `len``(arr)` `    ``print``(maximumGCD(arr, N, K))` `# This code is contributed by chitranayal`

## C#

 `// C# program to implement``// the above approach``using` `System;``class` `GFG``{``  ` `  ``// Recursive function to return gcd of a and b``  ``static` `int` `gcd(``int` `a, ``int` `b)``  ``{``    ` `    ``// Everything divides 0``    ``if` `(a == 0)``      ``return` `b;``    ``if` `(b == 0)``      ``return` `a;` `    ``// base case``    ``if` `(a == b)``      ``return` `a;` `    ``// a is greater``    ``if` `(a > b)``      ``return` `gcd(a-b, b);``    ``return` `gcd(a, b-a);``  ``}` `  ``// Function to return the maximum GCD``  ``// by taking each operation``  ``static` `int` `findGCD(``int` `x, ``int` `y, ``int` `z, ``int` `res)``  ``{``    ` `    ``// Store the maximum GCD obtained``    ``// by either incrementing, decrementing``    ``// or not changing A[i]``    ``int` `ans = gcd(x, res);``    ``ans = Math.Max(ans, gcd(y, res));``    ``ans = Math.Max(ans, gcd(z, res));` `    ``// Return the maximum GCD``    ``return` `ans;``  ``}` `  ``// Function to find the maximum GCD of``  ``// the array arrA[] by either increasing``  ``// or decreasing the array elements by K``  ``static` `int` `maximumGCD(``int``[] A, ``int` `N, ``int` `K)``  ``{``    ` `    ``// Initialize a dp table of size N*3``    ``int``[,] dp = ``new` `int``[N, 3];``    ``for` `(``int` `i = 0; i < N; i++) {``      ``for` `(``int` `j = 1; j < 3; j++) {``        ``dp[i, j] = 0;``      ``}``    ``}` `    ``// Base Cases:``    ``// If only one element is present``    ``dp[0, 0] = A[0];``    ``dp[0, 1] = A[0] + K;``    ``dp[0, 2] = A[0] - K;` `    ``// Traverse the array A[] over indices [1, N - 1]``    ``for` `(``int` `i = 1; i < N; i++) {` `      ``// Store the previous state results``      ``int` `x = dp[i - 1, 0];``      ``int` `y = dp[i - 1, 1];``      ``int` `z = dp[i - 1, 2];` `      ``// Store maximum GCD result``      ``// for each current state``      ``dp[i, 0] = findGCD(x, y, z, A[i]);``      ``dp[i, 1] = findGCD(x, y, z, A[i] + K);``      ``dp[i, 2] = findGCD(x, y, z, A[i] - K);``    ``}` `    ``// Store the required result``    ``int` `mx = Math.Max(3, Math.Max(dp[N - 1, 0], Math.Max(dp[N - 1, 1],``                                                         ``dp[N - 1, 2])));` `    ``// Return the result``    ``return` `mx;``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main()``  ``{``    ``int``[] arr = { 3, 9, 15, 24 };``    ``int` `K = 1;``    ``int` `N = arr.Length;` `    ``Console.Write( maximumGCD(arr, N, K));``  ``}``}` `// This code is contributed by susmitakundugoaldanga.`

## Javascript

 ``

Output:

`4`

Time Complexity: O(N*log(M)), where M is the smallest element in the array arr[]
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up