• 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]

    链接:https://leetcode.com/problems/minimum-moves-to-equal-array-elements/#/description

    3/26/2017

    我的答案,错误的!!!

    n * x = sum + (n - 1) * y, 其中x是最终每个元素的值,y是move的次数,sum是最初的和

    y = (n * x - sum)/(n - 1),只要y是整数就可以了。

    但是是错误的,为什么?有溢出,test case [1,1,2147483647]

     1 public class Solution {
     2     public int minMoves(int[] nums) {
     3         if (nums.length <= 1) return 0;
     4         int max = Integer.MIN_VALUE;
     5         int diffCount = 0;
     6         int sum = 0;
     7         for (int i = 0; i < nums.length; i++) {
     8             if (nums[i] > max) max = nums[i];
     9             sum += nums[i];
    10         }
    11         int element = max;
    12         while ((element * nums.length - sum) % (nums.length - 1) != 0) element++;
    13         return (element * nums.length - sum) / (nums.length - 1);
    14     }
    15 }

    之前是用最大值算的,答案是错的。尝试用最小值算却对了。为什么?

    标准答案里面第三种方法有解释,我总结来说:

    每次给最小的n-1个元素加上max-min的值,加过之后本来第二大元素成为新的最大值,之前最大元素和之前最小元素都是之前最大元素值。

    如此进行,每一步最小值的数目都在上升,至少加1(上一轮最大元素),或者更多(输入时最小值有重复,注意,只能是最小值,之后元素若有重复必然在过程中成为最大值)。而且,输入中的最小值,永远都是数组中的最小值!

    最后我们加了多少呢?最小值和每个元素值的差值和。(第一轮是与最大元素差值,第二轮是与输入次大元素差值,直到最后一轮是输入中次小元素差值)。

    解法很好写,过程很难想。为什么最大值不行?因为是往上加的过程?

    同样的代码还可以用来解释第五种方法,非常巧妙!

    每次给n-1个值加1,重复m次数之后的m其实相当于每次给1个值减1,重复m次。

    看到第6中解法,才发现用最小值求差的代码就是第六种啊哈哈

     1 public class Solution {
     2     public int minMoves(int[] nums) {
     3         if (nums.length <= 1) return 0;
     4         int min = Integer.MAX_VALUE;
     5         int moveCount = 0;
     6         for (int i = 0; i < nums.length; i++) {
     7             if (nums[i] < min) min = nums[i];
     8         }
     9         for (int i = 0; i < nums.length; i++) {
    10             if (nums[i] > min) moveCount += nums[i] - min;
    11         }
    12         return moveCount;
    13     }
    14 }

    标准答案:

    https://leetcode.com/articles/minimum-moves-to-equal-array-elements/

  • 相关阅读:
    个人收藏Sql
    使用Linq生成分类Json数据
    报表分页的页眉或页脚字段有的不显示
    工作流添加跟踪后,实例一启动就会自动关闭
    委托能不能序列化
    iframe加载完成后操作contentDocument
    WCF 异步调用
    自定义控件如何嵌入javascript 文件
    ReportViewer 使用DataSet 结构 与 linQ 填充 DataSet数据
    vs 2008 不能切换到设计视图的解决办法
  • 原文地址:https://www.cnblogs.com/panini/p/6624994.html
Copyright © 2020-2023  润新知