力扣(LeetCode)每日随机一题——2171.拿出最少的魔法豆[中等]

一、题目

拿出最少的魔法豆

123

二、代码

没做出来呜呜😢

// 思路是想要找到一个最后非空魔法袋中的魔法豆的数量,之后将小于其的全部拿走,大于的将多余部分拿走;但思考半天没想出要如何挑选这个数值,下面是错误尝试用中位数代替分割数
class Solution {
    public long minimumRemoval(int[] beans) {
        
        // 0
        ArrayList<Integer> list = new ArrayList<Integer>();
        Collections.addAll(list, Arrays.stream(beans).boxed().toArray(Integer[]::new));
        Collections.sort(list);

        int len = beans.length;
        int mid = (list.get(0)+list.get(len-1))/2;
        long res = 0;
        
        for(int i=0;i<len;i++) {
            if(beans[i] < mid) {
                res = res + beans[i];
            }else if(beans[i] > mid) {
                res = res + (beans[i]-mid);
            }
        }
        return res;
    }
}
// 在我重新整理过程中才发现这个“分割数”一定为beans数组中的一个,因为小于它的肯定都要去掉,只有选择beans数组中的一个,才会使得大于它的元素和它的差值最小
// 另外需要补充注释0的3行代码本来是想要实现将数组排序,因为不知道可以使用Arrays.sort(beans);从而麻烦的将其转换为Array然后又进行的排序(呜呜呜~好笨笨😢)

三、题解

思路

我们最后要达到的最终状态是除了0以外,其他所有豆子都一样的数目,假设这个数目为k。
每个袋子里有两种情况:

袋子原来豆子数目bean < k,此时该袋子里豆子要被全部拿走,拿走数目为bean。
袋子原来豆子数目bean > k,此时该袋子里豆子要被拿走bean - k。

解法

先排序,我们会发现当k是beans数组里本来就有的数字时,拿走的魔法豆会更小,而当k=beans[i]的时候,下标小于i的所有袋子,全部拿走,下标大于i的袋子,拿走到只有bean[i]个豆子。所以剩下的豆子如图所示:
先排序,我们会发现当k是beans数组里本来就有的数字时,拿走的魔法豆会更小,而当k=beans[i]的时候,下标小于i的所有袋子,全部拿走,下标大于i的袋子,拿走到只有bean[i]个豆子。所以剩下的豆子如图所示:
s因此我们进行一次遍历,计算出k=beans[i]的时候需要拿走的豆子数量就是豆子总数减掉图里蓝色长方形部分:total - beans[i] * (n - i)(这里n-i可通过具体例子验证,如i取0,即没有任何一个袋子里的豆需要被全部拿走,此时n-0=n正好是整个数组长度),遍历时维护一个值res,保存最小需要拿走的魔法豆数量即可。

代码

class Solution {

    public long minimumRemoval(int[] beans) {

        int n = beans.length;

        Arrays.sort(beans);

        long sum = 0;

        for(int j = 0; j < n; j++){

            sum += beans[j];

        }

        

        long temp = 0;

        long ans = sum;

        for(int i = 0; i < n; i++){

            // beans[i]是int32,因此必须加1L

            temp =  sum - 1L * (n-i) * beans[i];

            if(temp<ans) ans = temp;

        }

        return ans;

    }

}

来源:力扣(LeetCode

四、总结

其他:
① int数组排序使用Arrays.sort(int []n);
② 重新敲一遍的时候发现 temp = sum - 1L * (n-i) * beans[i]; 这里int转long要在前面乘1L

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值