LeetCode: 最小操作次数使数组元素相等

一、题目描述(数组的改变、移动)

给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。
输入:nums = [1,2,3]
输出:3
解释:
只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

二、错误解法

找出最大的一个数,剩下的数加1,不断重复该操作,停止该操作的条件是加数后的所有数相等。
这样做会超出时间限制

public class Arrray_453 {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3};
        int n = nums.length;
        boolean flag1 = true;
        int temp = 0;//用于记录最小数的位置
        int count = 0;//记录次数

        while (flag1) {

            //找出最大(最小是用来避免111这种情况)
            int min = 65535;
            int max = nums[0];
            for (int i = 0; i < n; i++) {
                if (nums[i] < min) {
                    min = nums[i];
                }
                if (nums[i] > max) {
                    max = nums[i];
                    temp = i;
                }
            }

            if (min == max) {
                return;//如果相等直接返回count
            }

            //进行加数
            for (int j = 0; j < n; j++) {
                if (j != temp) {
                    nums[j] = nums[j] + 1;
                    System.out.println(nums[j]);
                }
            }

            //检查所有数都一样
            int k=nums[0];
            boolean flag2 = true;
            while (flag2){
                for (int t = 1; t < n; t++) {
                    if (k != nums[t]) {
                        flag2 = false;
                        break;
                    } else {
                        if (t == n - 1) {
                            flag1 = false;
                            flag2 = false;
                        }
                    }
                }
            }
        count++;
        }
        System.out.println(count);
    }
}

三、正确解法

其实按照题目的意思也可以理解为每次的操作都是使最大的那个数减1,显然对多个数操作比对一个数操作复杂。
所以我们在解题的时候就转换思想为最终目标是让所有的数等于最小的那个数,因此需要操作的次数也就为数组中每一个数与该数组最小值的差值之和
而且以最小值为标准的一个好处是最小值一直都是哪一个不会变,而最大值在经过某次的加1之后会改变这就导致每次都要去找最大值

class Solution {
    public int minMoves(int[] nums) {
        int n = nums.length;
        int count=0;
        int sum=0;
        int min=nums[0];
        for (int i = 0; i < n; i++) {
            if (nums[i]<min){
                min=nums[i];
            }
        }
//        count=sum-min*n;//但是这样会有溢出问题
        //所以计算每个数和min的差
        for (int j = 0; j < n; j++) {
            sum=nums[j]-min;
            count+=sum;
        }
        return count;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值