LeetBook乐扣题库 453. 最小操作次数使数组元素相等

一 题目描述

给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。

示例 1:

输入:nums = [1,2,3]
输出:3
解释:
只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3]  =>  [2,3,3]  =>  [3,4,3]  =>  [4,4,4]

示例 2:

输入:nums = [1,1,1]
输出:0

二 方法代码

做题思路

三个思路展现出来的最终代码其实是一样的

思路1(也是最简便的)

按照相对理论来说,n-1个元素加1 <=> 一个元素减1,即每一个元素挨个减到最小值,一共要减几次

思路2

来自官方题解评论区的思路,算是正面推导,链接:大佬的评论区链接

思路3

假设一共要操作 k 次,对于最小的数来说,它一定是每一轮都在+1的,因为是它在追赶最高峰,永远不会让他轮空成为那个剩下的不+1的值。对于其他的数来说,其值 - min的结果便是这个数轮空不+1的次数,

所以公式为 k = \sum(其他数 - min)具体原理请见图:

取得最小值:

有三个办法,其中速度最快的是getMin3()

  • 方法一,getMin1()

int getMin1(int[] nums){
        //Arrays.stream(nums)将数组转换成一个流,可对数组中的元素进行各种操作
        //min()是流中的一个终端操作,对于IntStream,会返回一个包含最小值的OptionalInt对象
        //因为min()返回的是 OptionalInt,调用getAsInt()方法返回OptionalInt中的整数值
        int min = Arrays.stream(nums).min().getAsInt();
        return min;
    }
  • 方法二,getMin2()

int getMin2(int[] nums){
        //先排序,这个会改变nums数组,然后拿取第一个
        Arrays.sort(nums);
        return nums[0];
    }
  • 方法三,,getMin3()

int getMin3(int[] nums){
        int min = nums[0];
        for(int num : nums) {
            min = Math.min(num, min);
        }

        return min;
    }

总的代码:

public int minMoves(int[] nums) {
        int min = getMin3(nums);
        int sum = 0;

        //计算每一个数和min差值的和
        for(int i : nums){
            sum += i - min;
        }
        return sum;
    }

三 运行结果

分析速率的区别的原因:

对于getMin1():

  • 复杂度:这个方法的时间复杂度是 O(n),因为它只需要遍历数组一次,找到最小值。
  • 操作:该方法不会改变数组的顺序,这方法使用了流式 API,虽然同样只遍历数组一次,但涉及到流的创建和 OptionalInt 的处理。这些操作虽然不是很昂贵,但相比手动遍历会有一点额外的开销。
  • 开销:流的初始化和包装操作会引入额外的性能开销

对于getMin2():

  • Arrays.sort(nums) 使用的是双轴快速排序(Dual-Pivot Quicksort),其时间复杂度为 O(nlog⁡n)。
  • 操作:排序会对整个数组进行重新排列,然后从排好序的数组中取出第一个元素(最小值)。
  • 开销:排序操作不仅耗时,还会改变数组的顺序,且需要更多的内存(可能需要额外的空间用于排序)。如果数组很大,开销会更大。

对于getMin3():

  • 复杂度:时间复杂度是 O(n),其中 n 是数组的长度。它只需要遍历数组一次,每次比较两个元素并更新最小值。
  • 操作:直接遍历数组,逐个元素与当前最小值进行比较,不需要额外的内存或其他操作。
  • 优点:这是最直接和高效的方法,因其简单直接,没有额外的函数调用或不必要的操作。
  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值