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

109 阅读1分钟

题目:
给你一个  整数数组 beans ,其中每个整数表示一个袋子里装的魔法豆的数目。

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

请你返回你需要拿出魔法豆的 最少数目
算法:
方法一: 排序
思路:假设剩余的豆子为x,那么其他袋子里的豆子会变成怎么样?小于x的豆子会全部拿走,大于x的豆子会减少到x。 因此对beans进行排序,然后对于beans[i],计算i前面小于beans[i]的豆子之和,与i后面的每个口袋豆子与beans[i]之差的和,取最大值。

注意,我们总是思考最终状态,然后从这个状态出发,看有什么特征,然后进行计算。而不是模拟拿豆子的过程。

import "math"
func minimumRemoval(beans []int) int64 {
    ans := math.MaxInt64
    total := 0 
    n := len(beans)
    for i := range beans {
        total = total + beans[i]
    }
    sort.Ints(beans)
    smallerBeans := 0
    preIndex := 0
    pre := 0
    // fmt.Println(beans)
    for i := range beans {
        removeCount := 0
        if pre < beans[i]  {
            smallerBeans = smallerBeans + pre
            preIndex = i
        }
        removeCount = total - (n - preIndex) * beans[i]
        // fmt.Println(smallerBeans, removeCount)
        if removeCount < ans {
            ans = removeCount
        }
        
        pre = beans[i]
    }
    return int64(ans)
}