# 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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr[] = {3, 9, 15, 24}, K = 1
Output: 4
Explanation:
Perform the following operations on the array arr[]:
Increment arr by 1. Therefore, arr[] modifies to {4, 9, 15, 24}.
Decrement arr by 1. Therefore, arr[] modifies to {4, 8, 15, 24}.
Increment arr 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[], where dp[i], dp[i], and dp[i] 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[] by updating dp, dp and dp with arr, arr + K and arr – K respectively.
• Iterate over the range [1, N – 1] and perform the following steps:
• For dp[i], find the maximum GCD of A[i] with 3 previous states, i.e., dp[i – 1], dp[i – 1] and dp[i – 1] once at a time, and store the maximum result in dp[i].
• Similarly, store the results in dp[i] and dp[i] 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];``    ``memset``(dp, 0, ``sizeof``(dp));` `    ``// Base Cases:``    ``// If only one element is present``    ``dp = A;``    ``dp = A + K;``    ``dp = A - 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];``        ``int` `y = dp[i - 1];``        ``int` `z = dp[i - 1];` `        ``// Store maximum GCD result``        ``// for each current state``        ``dp[i] = findGCD(x, y, z, A[i]);``        ``dp[i] = findGCD(x, y, z, A[i] + K);``        ``dp[i] = findGCD(x, y, z, A[i] - K);``    ``}` `    ``// Store the required result``    ``int` `mx = max(``        ``{ 3, dp[N - 1], dp[N - 1],``          ``dp[N - 1] });` `    ``// Return the result``    ``return` `mx;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 3, 9, 15, 24 };``    ``int` `K = 1;``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``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;``    ``dp[0, 1] = A + K;``    ``dp[0, 2] = A - 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