2171.拿出最少数目的魔法豆

题目链接
题目描述: 给定一个 正整数 数组 beans ,其中每个整数表示一个袋子里装的魔法豆的数目。

排序+前缀和+后缀和

请你从每个袋子中 拿出 一些豆子(也可以 不拿出),使得剩下的 非空 袋子中(即 至少还有一颗 魔法豆的袋子)魔法豆的数目 相等。一旦把魔法豆从袋子中取出,你不能再将它放到任何袋子中。

请返回你需要拿出魔法豆的 最少数目。

分析:如果最后非空袋子的魔法豆数量为x,因为袋子中无法添加豆子,所以原本比x小的,只能全部取出。
此时只有两种情况:

  1. 原本魔法豆数量大于x:都变为x,假设有3个袋子数量大于x,那么就是这三个袋子魔法豆总数-3x,就是需要取出的魔法豆数量。
  2. 原本魔法豆数量小于x:全部取出。假设有4个袋子数量小于x,那么就是这四个魔法袋豆总数,就是需要取出的魔法豆数量。

也就是说,需要关注的数据有两个,比x大的元素之和,比x小的元素之和。
自然想到前缀和后缀和
先排序,做累加,即可得到前缀和与后缀和。
所有需要取出的魔法豆总数=前缀和+后缀和-beans[i]*(len-i-1)。i为排序后当前元素的下标
代码:

class Solution {
    public long minimumRemoval(int[] beans) {
        if(beans.length==1) {
            return 0;
        }
        Arrays.sort(beans);
        //preSum[i] 表示 [0,i)的累加
        long[] preSum = new long[beans.length];
        //afterSum[i] 表示(i,len-1]的累加
        long[] afterSum = new long[beans.length];
        for(int i=1; i<beans.length; i++) {
            preSum[i] = preSum[i-1] + beans[i-1];
            afterSum[beans.length-1-i] = afterSum[beans.length-i] + beans[beans.length-i];
        }

        long res = Long.MAX_VALUE;
        for(int i=0; i<beans.length; i++) {
            res = Math.min(res, preSum[i] + afterSum[i] - (long) (beans.length - i - 1) *beans[i]);
        }
        return res;
    }
}
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值