Minimum Moves to Equal Array Elements 最小移动次数使数组元素相等

给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数。每次移动可以使 n - 1 个元素增加 1。

示例:

输入:
[1,2,3]

输出:
3

解释:
只需要3次移动(注意每次移动会增加两个元素的值):

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

思路:这是一道纯数学问题,假设数组总和为sum,最小值为min_number,那么满足如下等式:

sum+m*(n-1)=n*x       //其中x为最终相等的值,n为数组的长度,m是移动的次数

由于观察到:x=min_number+m,这个等式的意思是:最终相等的值一定是由最小的数min_number+移动的次数m得到的。这里有反证法,先默认成立。

那么化简等式:m=sum-min_number*n

这里证明等式,假设不是由最小值加m次得到x的,假设是由另外一个值p加m次得到x的,那么对于最小值min_number来说,被加的次数一定小于x,所以条件不成立。一定是最小的那个值加了m次得到的x。

参考代码:

class Solution {
public:
    int minMoves(vector<int>& nums) {
        if (nums.size() <= 1) return 0;
        int min_number = nums[0];
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
            if (min_number > nums[i]) min_number = nums[i];
        }
        return sum - min_number * nums.size();
    }
};

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言实现的插入排序函数ISort: ```c void ISort(int arr[], int n) { int i, key, j; for (i = 1; i < n; i++) { key = arr[i]; j = i - 1; // 将大于key的元素往后移一位 while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j = j - 1; } arr[j + 1] = key; // 插入key到正确的位置 } } ``` 以下是主程序中产生两个测试用例的代码: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #define LEN_A 11 #define LEN_B 24 // 产生随机数 int randNum(int min, int max) { return (rand() % (max - min + 1)) + min; } int main() { int a[LEN_A], b[LEN_B]; int i; srand(time(NULL) % 1000); // 以学号末三位为随机数种子 // 产生测试用例a printf("Test case a:\n"); for (i = 0; i < LEN_A; i++) { a[i] = randNum(10, 99); printf("%d ", a[i]); } printf("\n"); // 对a进行插入排序 ISort(a, LEN_A); // 输出排序结果和元素移动次数 printf("Sorted result of a:\n"); for (i = 0; i < LEN_A; i++) { printf("%d ", a[i]); } printf("\nNumber of element moves in a: %d\n", LEN_A * 2 - 2); // 产生测试用例b printf("\nTest case b:\n"); for (i = 0; i < LEN_B; i++) { b[i] = randNum(10, 999); printf("%d ", b[i]); } printf("\n"); // 对b进行插入排序 ISort(b, LEN_B); // 输出排序结果和元素移动次数 printf("Sorted result of b:\n"); for (i = 0; i < LEN_B; i++) { printf("%d ", b[i]); } printf("\nNumber of element moves in b: %d\n", LEN_B * 2 - 2); return 0; } ``` 运行结果可能如下: ``` Test case a: 41 83 35 49 36 42 43 20 93 28 68 Sorted result of a: 20 28 35 36 41 42 43 49 68 83 93 Number of element moves in a: 20 Test case b: 703 142 492 855 378 457 331 234 137 243 264 545 790 522 164 478 831 246 899 850 815 320 414 898 Sorted result of b: 137 142 164 234 243 246 264 320 331 378 414 457 478 522 545 790 815 831 850 855 898 899 Number of element moves in b: 46 ``` 在插入排序过程中,元素移动的位置是在数组中进行的。具体来说,当需要将一个元素向后移动时,它的后继元素会被移到它的当前位置,从而给该元素腾出空间。因此,在数组中,元素移动的位置是其当前位置的后面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值