leetcode-453-Minimum Moves to Equal Array Elements

Topic description:

Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1.

Example:

Input:
[1,2,3]

Output:
3

Explanation:
Only three moves are needed (remember each move increments two elements):

[1,2,3]  =>  [2,3,3]  =>  [3,4,3]  =>  [4,4,4]

Function to be done:

int minMoves(vector<int>& nums) 

 

illustrate:

1. This question seems interesting.

Let's take an example of [1, 2, 3, 4] to see if we can find any rules.

[1,2,3,4], select the smallest 3 elements inside +1

[2,3,4,4], select the smallest 3 elements inside +1

[3,4,5,4], select the smallest 3 elements inside +1

[4,5,5,5], select the smallest 3 elements inside +1

[5,6,6,5], select the smallest 3 elements inside +1

[6,7,6,6], select the smallest 3 elements inside +1

[7,7,7,7], select the smallest 3 elements inside +1

We can find that when processing a vector, the smallest n-1 elements in it are always selected to +1. In this way, our intuition tells us that this is the fastest.

Indeed, if in the step [3,4,5,4], we do not choose the smallest three elements to process, but choose 4,5,4 to +1, the result will be [3,5,6, 5]. No matter how you deal with it later, it will not reach [7,7,7,7].

Pick the smallest n-1 elements to process, this is the fastest way to get to "all values ​​equal".

It stands to reason that, knowing this information, we can write code to simulate this process:

Each time the largest element is found, then the other elements except the largest element are +1.

Keep repeating processing until all elements are equal.

Output the number of times to repeat the process.

But I always feel that there is a smell that can directly calculate the output.

Let's go back and look again.

 

2. Mathematical methods

n-1 numbers + 1, if the process is repeated count times, then it is (n-1)*count, plus the value of the original n numbers, the result will be equal to all equal numbers (set as t)*n.

That is (n-1)*count+(the value of n numbers)=t*n.

The key is the value of t.

 

Let's go back and look at the example given in 1. In each processing, the minimum value of 1 is involved. A total of 6 times are added, and finally it becomes 7.

Intuition tells us that at the beginning, the minimum value will be added count times, that is, t should be min+count.

If this conclusion holds, the above formula can be solved for count.

Let's try it out, the code is as follows:

    int minMoves(vector<int>& nums) 
    {
        int min1=nums[ 0 ];//Record the minimum value
         int len= nums.size();
         int result=nums[ 0 ];//Record the sum of the values ​​in nums
         for ( int i= 1 ;i<len; i++ )
        {
            result+=nums[i];
            if(nums[i]<min1)
                min1=nums[i];
        }
        return result-min1*len;//我们要求的count
    }

submit,实测51ms,beats 94.55% of cpp submissions。通过了所有测试样例……

 

我们的直觉为什么是成立的?笔者在推[1,2,3,4]的时候,觉得直觉的想法应该大致是成立的,但是想给出一个数学上的解释就比较麻烦了。

姑且放过笔者吧……日后被remind到简单又好懂的推理方法再来补充。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324752180&siteId=291194637
Recommended