题目:
给你一个 正 整数数组 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)
}