「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」
575. 分糖果
Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。
医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。
给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的 最多 种类数。
示例 1:
输入:candyType = [1,1,2,2,3,3]
输出:3
解释:Alice 只能吃 6 / 2 = 3 枚糖,由于只有 3 种糖,她可以每种吃一枚。
示例 2:
输入:candyType = [1,1,2,3]
输出:2
解释:Alice 只能吃 4 / 2 = 2 枚糖,不管她选择吃的种类是 [1,2]、[1,3] 还是 [2,3],她只能吃到两种不同类的糖。
示例 3:
输入:candyType = [6,6,6,6]
输出:1
解释:Alice 只能吃 4 / 2 = 2 枚糖,尽管她能吃 2 枚,但只能吃到 1 种糖。
解法
数组去重
思路
先将数组去重,计算出数组中不同类型数组数量count。数组长度n,由于n为偶数,那么n/2一定为整数。
由于要在n/2的限制之内去吃到最多种类的糖,那么我们做如下分析:
- count > n/2, 也就是种类大于数量,那么我们可以count种类中,挑出n/2数量的糖,也就是最多可以吃到n/2颗糖。
- count = n/2, 也就是种类等于数量,那么我们把所有种类的一样挑一颗即可,也就是可以吃到count颗,且等于n/2颗。
- count < n/2, 也就是种类小于数量,那么我们最多只能把每个种类挑出来一颗,再挑就重复了,也就是最多可以吃到count颗。
因此可以得到,最多可以吃到糖的数量,是count和n/2的最小值,即Math.min(count, n/2)
。
那么其实可以到,我们这一题的重点就变成了数组去重了。那数组去重的方式有哪些呢?
这里列举一些比较常用的
- es6的Set数据类型
- 利用new Set(arr),将数组天然去重即可,再通过set的size方法可以求长度,如果想转回数组,那么Array.from(set)即可。
- 操作原数组,遇到重复的删除
- 通过for的双循环嵌套,判断如果数据相同则使用splice删除当前数据。
- 使用新数组,遇到重复的跳过,新的则放入新数组
- 申明一个新数组,遍历原数组,如果当前项在新数组里存在,则跳过,不存在则push进新数组里,最终返回新数组,这里判断是否存在方法就多了,indexOf,includes都可以。
大体上是这三种类型,如果再细分,则是遍历的方式不一样,或者判断是否存在的方式不一样而已。
我们这里就使用Set数据结构来做
代码
/**
* @param {number[]} candyType
* @return {number}
*/
var distributeCandies = function(candyType) {
let n = candyType.length;
let set = new Set(candyType);
let count = set.size;
return Math.min(n/2, count);
};
复杂度分析
时间复杂度:O(n)
空间复杂度:O(n)