Given an array arr[] of n positive integers, you can perform the following operation any number of times:
- Choose two indices i and j such that arr[i] >= arr[j].
- Replace arr[i] with arr[i] - arr[j].
After performing any number of valid operations, minimize the maximum value present in the array.
Examples:
Input: arr[] = [3, 2, 4]
Output: 1
Explanation:
1st Operation : We can pick 4 & 3, subtract 4-3 => [3, 2, 1]
2nd Operation : We can pick 3 & 2, subtract 3-2 => [1, 2, 1]
3rd Operation : We can pick 1 & 2, subtract 2-1 => [1, 1, 1]
4th Operation : We can pick 1 & 1, subtract 1-1 => [1, 0, 1]
5th Operation : We can pick 1 & 1, subtract 1-1 => [0, 0, 1]
After this no operation can be performed, so maximum no is left in the array is 1.Input: arr[] = [2, 4]
Output: 2
Explanation:
1st Operation : We can pick 4 & 2, subtract 4-2 => [2, 2]
2nd Operation : We can pick 2 & 2, subtract 2-2 => [0, 2]
After this no operation can be performed, so maximum no is left in the array is 2.
Table of Content
[Naive Approach] Simulate Subtraction - O(n * M) Time and O(1) Space
The idea is to simulate the given operation by repeatedly subtracting the smaller positive value from the larger value. This process is similar to the subtraction-based Euclidean algorithm and eventually reduces the maximum value to the GCD.
Working of Approach:
- Find the smallest positive element and the largest element in the array.
- Subtract the smallest value from the largest value.
- Repeat the process while more than one distinct positive value exists.
- When all positive elements become equal, that value is the GCD of the array.
- This value is the minimum possible maximum after all valid operations.
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
int minimumNumber(vector<int> &arr)
{
// Continue until all positive elements become equal
while (true)
{
int mn = INT_MAX;
int mx = 0;
int index = -1;
// Find the smallest positive and largest element
for (int i = 0; i < arr.size(); i++)
{
if (arr[i] > 0)
mn = min(mn, arr[i]);
if (arr[i] > mx)
{
mx = arr[i];
index = i;
}
}
// If all elements are zero
if (mx == 0)
return 0;
// If all positive elements are equal
if (mn == mx)
return mn;
// Perform the subtraction operation
arr[index] -= mn;
}
}
int main()
{
vector<int> arr = {3, 2, 4};
cout << minimumNumber(arr) << endl;
return 0;
}
import java.util.Arrays;
public class GFG {
public static int minimumNumber(int[] arr)
{
// Continue until all positive elements become equal
while (true) {
int mn = Integer.MAX_VALUE;
int mx = 0;
int index = -1;
// Find the smallest positive and largest
// element
for (int i = 0; i < arr.length; i++) {
if (arr[i] > 0)
mn = Math.min(mn, arr[i]);
if (arr[i] > mx) {
mx = arr[i];
index = i;
}
}
// If all elements are zero
if (mx == 0)
return 0;
// If all positive elements are equal
if (mn == mx)
return mn;
// Perform the subtraction operation
arr[index] -= mn;
}
}
public static void main(String[] args)
{
int[] arr = { 3, 2, 4 };
System.out.println(minimumNumber(arr));
}
}
def minimumNumber(arr):
# Continue until all positive elements become equal
while True:
mn = float('inf')
mx = 0
index = -1
# Find the smallest positive and largest element
for i in range(len(arr)):
if arr[i] > 0:
mn = min(mn, arr[i])
if arr[i] > mx:
mx = arr[i]
index = i
# If all elements are zero
if mx == 0:
return 0
# If all positive elements are equal
if mn == mx:
return mn
# Perform the subtraction operation
arr[index] -= mn
if __name__ == '__main__':
arr = [3, 2, 4]
print(minimumNumber(arr))
using System;
using System.Linq;
public class GFG {
public static int minimumNumber(int[] arr)
{
// Continue until all positive elements become equal
while (true) {
int mn = int.MaxValue;
int mx = 0;
int index = -1;
// Find the smallest positive and largest
// element
for (int i = 0; i < arr.Length; i++) {
if (arr[i] > 0)
mn = Math.Min(mn, arr[i]);
if (arr[i] > mx) {
mx = arr[i];
index = i;
}
}
// If all elements are zero
if (mx == 0)
return 0;
// If all positive elements are equal
if (mn == mx)
return mn;
// Perform the subtraction operation
arr[index] -= mn;
}
}
public static void Main()
{
int[] arr = { 3, 2, 4 };
Console.WriteLine(minimumNumber(arr));
}
}
function minimumNumber(arr)
{
// Continue until all positive elements become equal
while (true) {
let mn = Number.MAX_SAFE_INTEGER;
let mx = 0;
let index = -1;
// Find the smallest positive and largest element
for (let i = 0; i < arr.length; i++) {
if (arr[i] > 0)
mn = Math.min(mn, arr[i]);
if (arr[i] > mx) {
mx = arr[i];
index = i;
}
}
// If all elements are zero
if (mx === 0)
return 0;
// If all positive elements are equal
if (mn === mx)
return mn;
// Perform the subtraction operation
arr[index] -= mn;
}
}
// Driver Code
const arr = [ 3, 2, 4 ];
console.log(minimumNumber(arr));
Output
1
[Expected Approach] GCD - O(n * log(max(arr))) Time and O(1) Space
The idea is to observe that subtracting one element from another does not change the GCD of the array. Therefore, the minimum possible maximum value after performing the operations is simply the GCD of all elements.
Working of Approach:
- Initialize gcd as 0.
- Traverse every element of the array.
- Find the GCD of the current element and the previously calculated GCD.
- The GCD remains unchanged by the allowed subtraction operations.
- Return the GCD of all elements as the minimum possible maximum.
Let us understand with an example:
Input: arr[] = [3, 2, 4]
- For arr = [3, 2, 4], initially gcd = 0.
- For 3: gcd = __gcd(0, 3) = 3.
- For 2: gcd = __gcd(3, 2) = 1.
- For 4: gcd = __gcd(1, 4) = 1.
- Finally, return gcd = 1, so the output is 1.
#include <iostream>
#include <vector>
using namespace std;
int minimumNumber(vector<int> &arr)
{
int n = arr.size();
int gcd = 0;
// iterating over the array to find the gcd.
for (int i = 0; i < n; i++)
{
// finding gcd of current element and the previous gcd.
gcd = __gcd(gcd, arr[i]);
}
return gcd;
}
int main()
{
vector<int> arr = {3, 2, 4};
cout << minimumNumber(arr) << endl;
return 0;
}
import java.util.Arrays;
public class GFG {
// Function to find gcd of array elements.
static int __gcd(int a, int b)
{
if (b == 0)
return a;
return __gcd(b, a % b);
}
static int minimumNumber(int[] arr)
{
int n = arr.length;
int gcd = 0;
// iterating over the array to find the gcd.
for (int i = 0; i < n; i++) {
// finding gcd of current element and the
// previous gcd.
gcd = __gcd(gcd, arr[i]);
}
return gcd;
}
public static void main(String[] args)
{
int[] arr = { 3, 2, 4 };
System.out.println(minimumNumber(arr));
}
}
from math import gcd
from functools import reduce
def minimumNumber(arr):
# Iterating over the array to find the GCD.
res = reduce(gcd, arr)
return res
if __name__ == '__main__':
arr = [3, 2, 4]
print(minimumNumber(arr))
using System;
class GFG {
// Function to find gcd of two numbers.
static int __gcd(int a, int b)
{
if (b == 0)
return a;
return __gcd(b, a % b);
}
static int minimumNumber(int[] arr)
{
int n = arr.Length;
int gcd = 0;
// iterating over the array to find the gcd.
for (int i = 0; i < n; i++) {
// finding gcd of current element and the
// previous gcd.
gcd = __gcd(gcd, arr[i]);
}
return gcd;
}
static void Main()
{
int[] arr = { 3, 2, 4 };
Console.WriteLine(minimumNumber(arr));
}
}
function __gcd(a, b)
{
if (b === 0)
return a;
return __gcd(b, a % b);
}
function minimumNumber(arr)
{
let n = arr.length;
let gcd = 0;
// iterating over the array to find the gcd.
for (let i = 0; i < n; i++) {
// finding gcd of current element and the previous
// gcd.
gcd = __gcd(gcd, arr[i]);
}
return gcd;
}
// Driver Code
let arr = [ 3, 2, 4 ];
console.log(minimumNumber(arr));
Output
1