Given an array arr[] consisting of even integers. At each move, you can select any even number X from the array and divide all the occurrences of X by 2. The task is to find the minimum number of moves needed so that all the elements in the array become odd.
Examples:
Input: arr[] = {40, 6, 40, 20}
Output: 4
Move 1: Select 40 and divide all the occurrences
of 40 by 2 to get {20, 6, 20, 20}
Move 2: Select 20 and divide all the occurrences
of 20 by 2 to get {10, 6, 10, 10}
Move 3: Select 10 and divide all the occurrences
of 10 by 2 to get {5, 6, 5, 5}.
Move 4: Select 6 and divide it by 2 to get {5, 3, 5, 5}.
Input: arr[] = {2, 4, 16, 8}
Output: 4
Approach: This problem can be solved using greedy approach. At every move, take the largest remaining even number in the array and divide it by 2. The largest is taken because there is a chance that it can become equal to some other element in the array after it is divided by 2 which minimizes the total operations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minOperations( int arr[], int n)
{
set< int > s;
for ( int i = 0; i < n; i++) {
s.insert(arr[i]);
}
int moves = 0;
while (s.empty() == 0) {
int z = *(s.rbegin());
if (z % 2 == 0) {
moves++;
s.insert(z / 2);
}
s.erase(z);
}
return moves;
}
int main()
{
int arr[] = { 40, 6, 40, 20 };
int n = sizeof (arr) / sizeof ( int );
cout << minOperations(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int minOperations( int arr[], int n)
{
TreeSet<Integer> s = new TreeSet<Integer>();
for ( int i = 0 ; i < n; i++)
{
s.add(arr[i]);
}
int moves = 0 ;
while (s.size() != 0 )
{
Integer z = s.last();
if (z % 2 == 0 )
{
moves++;
s.add(z / 2 );
}
s.remove(z);
}
return moves;
}
public static void main (String[] args)
{
int arr[] = { 40 , 6 , 40 , 20 };
int n = arr.length;
System.out.println(minOperations(arr, n));
}
}
|
Python3
from collections import OrderedDict as mpp
def minOperations(arr, n):
s = mpp()
for i in range (n):
s[arr[i]] = 1
moves = 0
while ( len (s) > 0 ):
z = sorted ( list (s.keys()))[ - 1 ]
if (z % 2 = = 0 ):
moves + = 1
s[z / 2 ] = 1
del s[z]
return moves
arr = [ 40 , 6 , 40 , 20 ]
n = len (arr)
print (minOperations(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int minOperations( int []arr, int n)
{
SortedSet< int > s = new SortedSet< int >();
for ( int i = 0; i < n; i++)
{
s.Add(arr[i]);
}
int moves = 0;
while (s.Count != 0)
{
int z = s.Max;
if (z % 2 == 0)
{
moves++;
s.Add(z / 2);
}
s.Remove(z);
}
return moves;
}
public static void Main(String[] args)
{
int []arr = { 40, 6, 40, 20 };
int n = arr.Length;
Console.WriteLine(minOperations(arr, n));
}
}
|
Javascript
<script>
function findRemainders(n)
{
var vc = new Set();
for ( var i = 1; i <= Math.ceil(Math.sqrt(n)); i++)
vc.add(parseInt(n / i));
for ( var i = parseInt(n / Math.ceil(Math.sqrt(n))) - 1;
i >= 0; i--)
vc.add(i);
[...vc].sort((a, b) => a - b).forEach(it => {
document.write(it + " " );
});
}
var n = 5;
findRemainders(n);
</script>
|
Time Complexity: O(n*log(n))
Auxiliary Space: O(n)