Given an array arr[] of size N, the task is to find the smallest positive integer K such that incrementing or decrementing each array element by K at most once makes all elements equal. If it is not possible to make all array elements equal, then print -1.
Examples :
Input: arr[] = { 5, 7, 9 }
Output: 2
Explanation:
Incrementing the value of arr[0] by K(= 2) modifies arr[] to { 7, 7, 9 }.
Decrementing the value of arr[2] by K(= 2) modifies arr[] to { 7, 7, 7 }
Input: arr[] = {1, 3, 9}, N = 3
Output: -1
Approach: Follow the steps below to solve the problem :
- Initialize a Set to store all distinct elements present in the array.
- Count the distinct elements in the array, which is equal to the size of the Set, say M.
- If M > 3, then print -1.
- If M = 3, then check if the difference between the largest and the second largest element of the Set is equal to the difference between the second largest and the third largest element of the Set or not. If found to be true, then print the difference. Otherwise, print -1.
- If M = 2, then check if the difference between the largest and the second largest element of the set is even or not. If found to be true, then print the half of their difference. Otherwise, print the difference.
- If M <= 1, then print 0.
Below is the implementation of the above solution :
C++
#include <iostream>
#include <set>
using namespace std;
void findMinKToMakeAllEqual( int N, int A[])
{
set< int > B;
for ( int i = 0; i < N; i++)
B.insert(A[i]);
int M = B.size();
set< int >::iterator itr = B.begin();
if (M > 3)
printf ( "-1" );
else if (M == 3) {
int B_1 = *itr;
int B_2 = *(++itr);
int B_3 = *(++itr);
if (B_2 - B_1 == B_3 - B_2)
printf ( "%d" , B_2 - B_1);
else
printf ( "-1" );
}
else if (M == 2) {
int B_1 = *itr;
int B_2 = *(++itr);
if ((B_2 - B_1) % 2 == 0)
printf ( "%d" , (B_2 - B_1) / 2);
else
printf ( "%d" , B_2 - B_1);
}
else
printf ( "%d" , 0);
}
int main()
{
int A[] = { 1, 3, 5, 1 };
int N = sizeof (A) / sizeof (A[0]);
findMinKToMakeAllEqual(N, A);
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void findMinKToMakeAllEqual( int N, int A[])
{
Set<Integer> B = new HashSet<Integer>();
for ( int i = 0 ; i < N; i++)
{
B.add(A[i]);
}
ArrayList<Integer> b = new ArrayList<Integer>(B);
int M = b.size();
int i = 0 ;
if (M > 3 )
{ System.out.print( "-1" );}
else if (M == 3 )
{
int B_1 = b.get(i++);
int B_2 = b.get(i++);
int B_3 = b.get(i++);
if (B_2 - B_1 == B_3 - B_2)
{
System.out.print(B_2 - B_1);
}
else
{
System.out.print( "-1" );
}
}
else if (M == 2 )
{
int B_1 = b.get(i++);
int B_2 = b.get(i++);
if ((B_2 - B_1) % 2 == 0 )
{
System.out.print((B_2 - B_1) / 2 );
}
else
{
System.out.print(B_2 - B_1);
}
}
else
{
System.out.print( 0 );
}
}
public static void main (String[] args)
{
int A[] = { 1 , 3 , 5 , 1 };
int N = A.length;
findMinKToMakeAllEqual(N, A);
}
}
|
Python3
def findMinKToMakeAllEqual(N, A):
B = {}
for i in range (N):
B[A[i]] = 1
M = len (B)
itr, i = list (B.keys()), 0
if (M > 3 ):
print ( "-1" )
elif (M = = 3 ):
B_1, i = itr[i], i + 1
B_2, i = itr[i], i + 1
B_3, i = itr[i], i + 1
if (B_2 - B_1 = = B_3 - B_2):
print (B_2 - B_1)
else :
print ( "-1" )
elif (M = = 2 ):
B_1, i = itr[i], i + 1
B_2, i = itr[i], i + 1
if ((B_2 - B_1) % 2 = = 0 ):
print ((B_2 - B_1) / / 2 )
else :
print (B_2 - B_1)
else :
print ( 0 )
if __name__ = = '__main__' :
A = [ 1 , 3 , 5 , 1 ]
N = len (A)
findMinKToMakeAllEqual(N, A)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void findMinKToMakeAllEqual( int N, int [] A)
{
var B = new HashSet< int >();
for ( int i = 0; i < N; i++) {
B.Add(A[i]);
}
List< int > b = new List< int >(B);
int M = b.Count;
int j = 0;
if (M > 3) {
Console.Write( "-1" );
}
else if (M == 3) {
int B_1 = b[j++];
int B_2 = b[j++];
int B_3 = b[j++];
if (B_2 - B_1 == B_3 - B_2) {
Console.Write(B_2 - B_1);
}
else {
Console.Write( "-1" );
}
}
else if (M == 2) {
int B_1 = b[j++];
int B_2 = b[j++];
if ((B_2 - B_1) % 2 == 0) {
Console.Write((B_2 - B_1) / 2);
}
else {
Console.Write(B_2 - B_1);
}
}
else {
Console.Write(0);
}
}
public static void Main( string [] args)
{
int [] A = { 1, 3, 5, 1 };
int N = A.Length;
findMinKToMakeAllEqual(N, A);
}
}
|
Javascript
<script>
function findMinKToMakeAllEqual(N, A)
{
var B = new Set();
for ( var i = 0; i < N; i++)
B.add(A[i]);
var M = B.size;
var itr = [...B].sort((a, b) => a - b);
if (M > 3)
document.write( "-1" );
else if (M == 3)
{
var B_1 = itr[0];
var B_2 = itr[1];
var B_3 = itr[2];
if (B_2 - B_1 == B_3 - B_2)
document.write(B_2 - B_1);
else
document.write( "-1" );
}
else if (M == 2)
{
var B_1 = itr[0];
var B_2 =itr[1];
if ((B_2 - B_1) % 2 == 0)
document.write(parseInt((B_2 - B_1) / 2));
else
document.write(B_2 - B_1);
}
else
document.write(0);
}
var A = [ 1, 3, 5, 1 ];
var N = A.length;
findMinKToMakeAllEqual(N, A);
</script>
|
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Another Approach:
- Find the minimum and maximum elements in the array.
- Initialize minElement and maxElement as the first element of the array.
- Iterate through the array and update minElement and maxElement accordingly.
- If the current element is less than minElement, update minElement.
- If the current element is greater than maxElement, update maxElement.
2. Check if all elements are already equal.
- If minElement is equal to maxElement, then all elements are already equal, and the smallest positive integer K is 0. Return 0.
3. Check if it’s possible to make all elements equal.
- If the difference between maxElement and minElement is odd, it’s not possible to make all elements equal by incrementing or decrementing them. Return -1.
4. Calculate the value of ‘diff’ as half of the difference between maxElement and minElement.
- diff = (maxElement – minElement) / 2
5. Check if it’s possible to make all elements equal by adding or subtracting ‘diff’.
- Iterate through the array.
- If the current element is not equal to minElement, maxElement, or minElement + diff, it’s not possible to make all elements equal. Return -1.
6. Return ‘diff’ as the smallest positive integer K.
- ‘diff’ is the value by which each array element needs to be incremented or decremented to make all elements equal.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int findSmallestK(vector< int >& arr) {
int n = arr.size();
int minElement = *min_element(arr.begin(), arr.end());
int maxElement = *max_element(arr.begin(), arr.end());
if (minElement == maxElement) {
return 0;
}
if ((maxElement - minElement) % 2 != 0) {
return -1;
}
int diff = (maxElement - minElement) / 2;
for ( int i = 0; i < n; i++) {
if (arr[i] != minElement && arr[i] != maxElement && arr[i] != minElement + diff) {
return -1;
}
}
return diff;
}
int main() {
vector< int > arr = { 5, 7, 9 };
int smallestK = findSmallestK(arr);
cout << smallestK << endl;
return 0;
}
|
Java
import java.util.*;
public class GFG {
public static int findSmallestK(List<Integer> arr) {
int n = arr.size();
int minElement = Collections.min(arr);
int maxElement = Collections.max(arr);
if (minElement == maxElement) {
return 0 ;
}
if ((maxElement - minElement) % 2 != 0 ) {
return - 1 ;
}
int diff = (maxElement - minElement) / 2 ;
for ( int i = 0 ; i < n; i++) {
if (arr.get(i) != minElement && arr.get(i) != maxElement && arr.get(i) != minElement + diff) {
return - 1 ;
}
}
return diff;
}
public static void main(String[] args) {
List<Integer> arr = new ArrayList<>(Arrays.asList( 5 , 7 , 9 ));
int smallestK = findSmallestK(arr);
System.out.println(smallestK);
}
}
|
Python3
def find_smallest_k(arr):
n = len (arr)
min_element = min (arr)
max_element = max (arr)
if min_element = = max_element:
return 0
if (max_element - min_element) % 2 ! = 0 :
return - 1
diff = (max_element - min_element) / / 2
for i in range (n):
if arr[i] ! = min_element and arr[i] ! = max_element and arr[i] ! = min_element + diff:
return - 1
return diff
if __name__ = = "__main__" :
arr = [ 5 , 7 , 9 ]
smallest_k = find_smallest_k(arr)
print (smallest_k)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
namespace SmallestKEqualization
{
class Program
{
static int FindSmallestK(List< int > arr)
{
int n = arr.Count;
int minElement = arr.Min();
int maxElement = arr.Max();
if (minElement == maxElement)
{
return 0;
}
if ((maxElement - minElement) % 2 != 0)
{
return -1;
}
int diff = (maxElement - minElement) / 2;
foreach ( int num in arr)
{
if (num != minElement && num != maxElement && num != minElement + diff)
{
return -1;
}
}
return diff;
}
static void Main( string [] args)
{
List< int > arr = new List< int > { 5, 7, 9 };
int smallestK = FindSmallestK(arr);
Console.WriteLine(smallestK);
Console.ReadKey();
}
}
}
|
Time Complexity: O(N)
Auxiliary Space: O(1)