算法小知识----11.03----分糖果

387 阅读2分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

分糖果

该题出自力扣的575——分糖果(简单题),题解经过自我消化

审题

给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果, 每一个数字代表一个糖果。你需要把这些糖果平均分给一个弟弟和一个妹妹。返回妹妹可以获得的最大糖果的种类数

  • 简单来说就是把数组内的种类最大化

  • 解析:

    • 由于要分类数组内的最大种类,所以首先需要一个空间去存储种类

    • 要获得最大的种类:

      • 因为是偶数长度的数组,所以这里会相对简单
      • 需要平均分给弟弟和妹妹,这里也是给出了简单
    • 由于妹妹和弟弟之间需要平均,所以这里就规定了妹妹的长度为数组的一半

      • 但是我们要求的并不是妹妹的长度;而是长度里面的种类
      • 在妹妹的长度里面,其实存在一个极限值——当数组内的种类 > 数组的长度 / 2时,妹妹的种类就为数组的一半
      • 当数组内的种类不足一半时,则可以直接返回种类长度
    • 综上所述,答案的区间为 [种类长度,数组长度 / 2]

编码

最初想法

在最开始,思路是正确的,但是过分沦陷在妹妹的数组长度上,没有跳出来看整个种类;导致了花费大量的时间复杂度去计算长度

    public static int distributeCandies(int[] candyType) {
​
        int length = candyType.length;
        HashMap<Integer,Integer> map = new HashMap<>(length);
        for (int num:candyType){
            if (map.containsKey(num)){
                map.put(num,map.get(num)+1);
            }else {
                map.put(num,1);
            }
        }
        Integer index = 0;
        for (int num:candyType){
            if (map.get(num) == 1){
                ++index;
            }
        }
        int result = length /2;
        if (index >= result){
            return result;
        }else {
            return index + (map.size() - index >result- index?result- index:map.size() - index);
        }
    }

1635756023(1).jpg

修复

在消化了官方题解后,恍然大悟,跳出数组长度,重新看这道题,自己做的操作仿佛无用功;

public static int distributeCandies(int[] candyType) {
    Set<Integer> set = new HashSet<>();
    for (int num:candyType){
        set.add(num);
    }
    return Math.min(set.size(),candyType.length / 2);
}

1635756129(1).jpg