arraysalgorithm

Minimize the number of operation to make all elements of array equal


Given an array of n elements you are allowed to perform only 2 kinds of operation to make all elements of array equal.

  1. multiply any element by 2
  2. divide element by 2(integer division)

Your task is to minimize the total number of above operation performed to make all elements of array equal.

Example

array = [3,6,7] minimum operation is 2 as 6 and 7 can be divided by 2 to obtain 3.

I cannot think of even the brute force solution.

Constraints 1 <= n <= 100000 and 1 <= ai <=100000 where ai is the ith element of array.


Solution

    1. View all numbers as strings of 0 and 1, via their binary expansion.

    E.g.: 3, 6, 7 are represented as 11, 110, 111, respectively.

    1. Dividing by 2 is equivalent to removing the right most 0 or 1, and multiplying by 2 is equivalent to adding a 0 from the right.

    For a string consisting of 0 and 1, let us define its "head" to be a substring that is the left several terms of the string, which ends with 1. E.g.: 1100101 has heads 1, 11, 11001, 1100101.

    1. The task becomes finding longest common head of all the given strings, and then determining how many 0's to add after this common head.

    An example:

    Say you have the following strings:

    10101001, 101011, 10111, 1010001

    1. find the longest common head of 10101001 and 101011, which is 10101;
    2. find the longest common head of 10101 and 10111, which is 101;
    3. find the longest common head of 101 and 1010001, which is 101.

    Then you are sure that all the numbers should become a number of the form 101 00....

    To determine how many 0's to add after 101, find the number of consecutive 0's directly following 101 in every string:

    For 10101001: 1

    For 101011: 1

    For 10111: 0

    For 1010001: 3

    It remains to find an integer k that minimizes |k - 1| + |k - 1| + |k - 0| + |k - 3|. Here we find k = 1. So every number should becomd 1010 in the end.