• leetcode-453-Minimum Moves to Equal Array Elements


    题目描述:

    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]

    要完成的函数:

    int minMoves(vector<int>& nums) 

     

    说明:

    1、这道题看起来有点意思。

    我们先举一个[1,2,3,4]的例子,看能不能发现点什么规律。

    [1,2,3,4],挑选里面最小的3个元素+1

    [2,3,4,4],挑选里面最小的3个元素+1

    [3,4,5,4],挑选里面最小的3个元素+1

    [4,5,5,5],挑选里面最小的3个元素+1

    [5,6,6,5],挑选里面最小的3个元素+1

    [6,7,6,6],挑选里面最小的3个元素+1

    [7,7,7,7],挑选里面最小的3个元素+1

    我们可以发现在处理vector的时候,总是会选择里面最小的n-1个元素来+1。这样子处理,直觉告诉我们这是最快的。

    的确如此,假如在[3,4,5,4]这一步,我们不选择最小的三个元素来处理,而是选择4,5,4来+1,结果会是[3,5,6,5]。后续无论怎样处理都达不到[7,7,7,7]了。

    选择最小的n-1个元素来处理,这是最快达到“所有数值都相等”的方法。

    按理来说,知道了这些信息,我们就可以写代码来模拟这个过程:

    每次找到最大元素,然后把除了最大元素的其他元素+1。

    不断重复处理,直到所有元素都相等。

    输出重复处理的次数。

    但是总觉得这里面有一缕能够直接计算输出的味道。

    我们再回过头来看一下。

     

    2、数学方法

    n-1个数+1,如果重复处理count次,那么就是(n-1)*count,加上原本n个数的数值,加完结果会等于所有相等的数(设为t)*n。

    也就是(n-1)*count+(n个数的数值)=t*n。

    关键就在于t的值了。

    我们回过头看一下1中举的例子,每一次的处理,最小值1都参与,一共加了6次,最后变成7。

    直觉告诉我们,最开始时候最小值会加上count次,也就是t应该是min+count。

    如果这个结论成立的话,上述式子就可以解出count来了。

    我们尝试一下,代码如下:

        int minMoves(vector<int>& nums) 
        {
            int min1=nums[0];//记录最小值
            int len=nums.size();
            int result=nums[0];//记录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到简单又好懂的推理方法再来补充。

  • 相关阅读:
    please get a license from www.texturepacker.com
    2014阿里巴巴WEB前端实习生在线笔试题
    javascript实现日期时间动态显示
    NHibernate之旅(8):巧用组件之依赖对象
    软工视频再识
    Android ListView 的优化
    hdu 5001 概率DP 图上的DP
    Android 代码设置Activity 背景透明
    内存数据网格IMDG简单介绍
    JavaFX2
  • 原文地址:https://www.cnblogs.com/chenjx85/p/8920996.html
Copyright © 2020-2023  润新知