Open In App

Convert Array such that no two even or odd numbers are adjacent

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[], the task is to print the minimum number of operations required to convert the array such that neither two even elements are adjacent nor two odd numbers are adjacent. In other words arr[i]%2 != arr[i+1]%2. For that, you can perform certain operations. (consider 0-based indexing)

  • In one operation you can choose any index i and perform arr[i] = floor(arr[i]/2).
  • You can perform this operation on a single index as many times as you want but each time count of operations increases.

Examples:

Input: arr[] = [4, 10, 10, 6, 2]
Output: 2
Explanation: Choose index 1 and divide  it by 2: the new array is [4, 5, 10, 6, 2].
Choose index 3 and divide it by 2: the new array is [4, 5, 10, 3, 2].

Input: arr[] = [4, 20, 10, 6, 2]
Output: 3
Explanation: Choose index 1 and divide it by 2 two times: the new array is [4, 5, 10, 6, 2].
Choose index 3 and divide it by 2: the new array is [4, 5, 10, 3, 2].

Approach: To solve the problem follow the below idea:

The only two possible orders are:

  • odd, even, odd, even, odd, even, ……..
  • even, odd, even, odd, even, odd, ……..

Precompute and store the number of operations needed by each element of the array to convert it to even and odd forms and then try two permutations. In each permutation, the total number of operations is calculated by adding the minimum number of operations required to convert each element in the permutation and print the minimum of the two permutations.

Follow the steps to solve the problem:

  • Initialize a vector of pair of int vector<pair<int, int>> say dp, the first integer of the pair will store the number of operations required by it to convert it to odd, and the second integer will store the number of operations required by it to convert it to even.
  • Iterate the array arr[] and for each element, compute the minimum number of operations required to convert it to odd and even and store the result in the dp[] array.
  • For each element arr[i], check if it is even, the number of divisions required to make it even is 0, dp[i].second = 0 and divide the number by 2, till it becomes an odd number and store the number of divisions in dp[i].first.
  • Else, the number of divisions required to make it odd is 0, dp[i].first = 0 and divide the number by 2, till it becomes an even number, and store the number of divisions in dp[i].second.
  • Try two permutations: (1) odd, even, odd, even, …, and (2) even, odd, even, odd, ….
    • In each permutation, the total number of operations is calculated by adding the minimum number of operations required to convert each element in the permutation.
  • Return the minimum of the two permutations.

Below is the implementation for the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
int convertArray(vector<int> arr)
{
 
    // Size of the vector
    int n = arr.size();
 
    // Initializing the vector dp to store
    // count of operations
    vector<pair<int, int> > dp(n);
 
    // Precomputing of values how many
    // steps required to convert the
    // current element to odd and even
    for (int i = 0; i < n; i++) {
 
        if (arr[i] % 2 == 0) {
            dp[i].second = 0;
 
            int cnt = 0;
            int x = arr[i];
 
            while (x % 2 == 0) {
                x = x / 2;
                cnt++;
            }
 
            dp[i].first = cnt;
        }
 
        else {
            dp[i].first = 0;
 
            int cnt = 0;
            int x = arr[i];
 
            while (x % 2 != 0) {
                x = x / 2;
                cnt++;
            }
 
            dp[i].second = cnt;
        }
    }
 
    // Trying (odd even odd even...)
    // permutaion
    int ans1 = 0;
 
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) {
            ans1 += dp[i].first;
        }
        else
            ans1 += dp[i].second;
    }
 
    // Trying (even odd even odd ...)
    // permutaion
    int ans2 = 0;
 
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) {
            ans2 += dp[i].second;
        }
        else
            ans2 += dp[i].first;
    }
 
    return min(ans1, ans2);
}
 
// Driver funtion
int main()
{
 
    vector<int> arr = { 4, 20, 10, 6, 2 };
    int steps = convertArray(arr);
 
    // Function Call
    cout << steps << endl;
    return 0;
}


Java




/*package whatever // do not write package name here */
 
import java.io.*;
import java.lang.*;
 
class GFG {
 
    static int convertArray(int arr[], int n)
    {
 
        // initializing the vector dp to store count of
        // operations
 
        int[][] dp = new int[n][2];
 
        // precomputing of values how many steps required to
        // convert the current element to odd and even
        for (int i = 0; i < n; i++) {
 
            if (arr[i] % 2 == 0) {
                dp[i][1] = 0;
 
                int cnt = 0;
                int x = arr[i];
 
                while (x % 2 == 0) {
                    x = x / 2;
                    cnt++;
                }
 
                dp[i][0] = cnt;
            }
 
            else {
                dp[i][0] = 0;
 
                int cnt = 0;
                int x = arr[i];
 
                while (x % 2 != 0) {
                    x = x / 2;
                    cnt++;
                }
 
                dp[i][1] = cnt;
            }
        }
 
        // trying (odd even odd even...) permutaion
        int ans1 = 0;
 
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                ans1 += dp[i][0];
            }
            else
                ans1 += dp[i][1];
        }
 
        // trying (even odd even odd ...) permutaion
        int ans2 = 0;
 
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                ans2 += dp[i][1];
            }
            else
                ans2 += dp[i][0];
        }
 
        // returning the minimum of the 2 values
        return Math.min(ans1, ans2);
    }
 
    public static void main(String[] args)
    {
        int[] arr = { 4, 20, 10, 6, 2 };
        int n = arr.length;
 
        int steps = convertArray(arr, n);
        System.out.println(steps);
    }
}


Python3




def convertArray(arr):
 
    # Size of the list
    n = len(arr)
 
    # Initializing the list dp to store
    # count of operations
    dp = [(0, 0)] * n
 
    # Precomputing of values how many
    # steps required to convert the
    # current element to odd and even
    for i in range(n):
 
        if arr[i] % 2 == 0:
            dp[i] = (0, 0)
 
            cnt = 0
            x = arr[i]
 
            while x % 2 == 0:
                x //= 2
                cnt += 1
 
            dp[i] = (cnt, 0)
 
        else:
            dp[i] = (0, 0)
 
            cnt = 0
            x = arr[i]
 
            while x % 2 != 0:
                x //= 2
                cnt += 1
 
            dp[i] = (0, cnt)
 
    # Trying (odd even odd even...)
    # permutation
    ans1 = 0
 
    for i in range(n):
        if i % 2 == 0:
            ans1 += dp[i][0]
        else:
            ans1 += dp[i][1]
 
    # Trying (even odd even odd ...)
    # permutation
    ans2 = 0
 
    for i in range(n):
        if i % 2 == 0:
            ans2 += dp[i][1]
        else:
            ans2 += dp[i][0]
 
    return min(ans1, ans2)
 
# Driver function
if __name__ == '__main__':
    arr = [4, 20, 10, 6, 2]
    steps = convertArray(arr)
 
    # Function Call
    print(steps)


C#




// C# code to implement the approach
using System;
 
class GFG {
 
    static int convertArray(int[] arr, int n)
    {
 
        // initializing the vector dp to store count of
        // operations
 
        int[][] dp = new int[n][];
        for (int i = 0; i < n; i++)
        {
            dp[i] = new int[2];
        }
 
        // precomputing of values how many steps required to
        // convert the current element to odd and even
        for (int i = 0; i < n; i++) {
 
            if (arr[i] % 2 == 0) {
                dp[i][1] = 0;
 
                int cnt = 0;
                int x = arr[i];
 
                while (x % 2 == 0) {
                    x = x / 2;
                    cnt++;
                }
 
                dp[i][0] = cnt;
            }
 
            else {
                dp[i][0] = 0;
 
                int cnt = 0;
                int x = arr[i];
 
                while (x % 2 != 0) {
                    x = x / 2;
                    cnt++;
                }
 
                dp[i][1] = cnt;
            }
        }
 
        // trying (odd even odd even...) permutaion
        int ans1 = 0;
 
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                ans1 += dp[i][0];
            }
            else
                ans1 += dp[i][1];
        }
 
        // trying (even odd even odd ...) permutaion
        int ans2 = 0;
 
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                ans2 += dp[i][1];
            }
            else
                ans2 += dp[i][0];
        }
 
        // returning the minimum of the 2 values
        return Math.Min(ans1, ans2);
    }
 
    public static void Main()
    {
        int[] arr = { 4, 20, 10, 6, 2 };
        int n = arr.Length;
 
        int steps = convertArray(arr, n);
        Console.WriteLine(steps);
    }
}
 
// This code is contributed by Pushpesh Raj


Javascript




function convertArray(arr, n) {
  let dp = new Array(n).fill().map(() => new Array(2).fill(0));
 
  for (let i = 0; i < n; i++) {
    if (arr[i] % 2 === 0) {
      dp[i][1] = 0;
 
      let cnt = 0;
      let x = arr[i];
 
      while (x % 2 === 0) {
        x = x / 2;
        cnt++;
      }
 
      dp[i][0] = cnt;
    } else {
      dp[i][0] = 0;
 
      let cnt = 0;
      let x = arr[i];
 
      while (x % 2 !== 0) {
        x = x / 2;
        cnt++;
      }
 
      dp[i][1] = cnt;
    }
  }
 
  let ans1 = 0;
  for (let i = 0; i < n; i++) {
    if (i % 2 === 0) {
      ans1 += dp[i][0];
    } else {
      ans1 += dp[i][1];
    }
  }
 
  let ans2 = 0;
  for (let i = 0; i < n; i++) {
    if (i % 2 === 0) {
      ans2 += dp[i][1];
    } else {
      ans2 += dp[i][0];
    }
  }
 
  return Math.min(ans1, ans2);
}
 
let arr = [4, 20, 10, 6, 2];
let n = arr.length;
let steps = convertArray(arr, n);
console.log(steps);


Output

3

Time complexity: O(n*logn)
Auxiliary Space: 0(N*2)



Last Updated : 13 Jul, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads