贪心猫的鱼干大分配 | 豆包MarsCode AI刷题

44 阅读3分钟

题目分析

分析题意可以知道本题需要使用索引对数组左右的数值进行比较,则需要保留元素对应位置,同时等级值会影响分配,而直接进行排序会导致丢失原有顺序,导致无法完成邻居条件。
因此可以考虑采用复制一份数组进行排序的方法,确保等级值能够进行排序,并且保留原有顺序。

AI分析

使用Marscode AI解题分析题意

public static int solution(int n, List<Integer> cats_levels) {
        // 初始化每只猫的鱼干分配,每只猫至少1斤
        List<Integer> fish_distribution = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            fish_distribution.add(1);
        }

        // 调整鱼干分配,确保等级高的猫分配的鱼干多于等级低的邻居
        // 从左到右遍历
        for (int i = 1; i < n; i++) {
            if (cats_levels.get(i) > cats_levels.get(i - 1)) {
                fish_distribution.set(i, fish_distribution.get(i - 1) + 1);
            }
        }

        // 从右到左遍历,确保分配满足条件
        for (int i = n - 2; i >= 0; i--) {
            if (cats_levels.get(i) > cats_levels.get(i + 1)) {
                fish_distribution.set(i, Math.max(fish_distribution.get(i), fish_distribution.get(i + 1) + 1));
            }
        }

        // 计算总的鱼干数量
        int total_fish = 0;
        for (int fish : fish_distribution) {
            total_fish += fish;
        }

        return total_fish;
    }

以上是AI给出的解题思路,使用的是简单的两次遍历来分配鱼干,设定的数值为比较对象+1,确保能够大于比较对象。
但是该算法存在一定的问题,问题在于在调整鱼干分配部分,一次遍历保证了所有猫与一边的猫之间的关系符合题目条件,但是在第二次遍历的时候会对于鱼干的数量进行修改,不能保证第一次遍历的方向上仍然符合题目条件。

解题思路

将左右遍历比较的方法较复杂,可能需要使用递归的方法。但是考虑到填空问题,先把战斗力最小的部分填上,然后依次比较,保证每一个都能够分配到最少的鱼干。

代码实现

首先将每个猫分配到的鱼干初始化为0,之后复制一份排序等级的猫列表并且进行排序。
由于排序是升序的,所以直接从0开始进行遍历,确保所有等级的猫都有进行分配操作。
再次嵌套循环,找到未排序的猫列表中等级与当前等级相同的,即未进行分配的最低等级。之后将其当前鱼干数量设定为左右鱼干数量+1,确保均大于两边同时又是最小的。
最后进行遍历,获得鱼干的总数量进行返回

代码纠错

for (int i = 0; i < n; i++) {
         int level = cats_levels_sort.get(i);

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

             if (cats_levels.get(j) == level) {
                 fishList.set(j, Math.max(
                         j > 0? fishList.get(j - 1) + 1 : 1,
                         j < n - 1 ? fishList.get(j + 1) + 1 : 1));
             }
         }
     }

这是最初的左右比较设定鱼干数量的算法,考虑到了边界情况,即越界情况,最左边的猫不需要进行左边的比较,同理最右边的猫不需要进行右边的比较。
但是通过测试发现并不对,通过对代码内部增加system.printf.out输出进行排查错误后查明,是因为没有考虑到相等的情况不需要进行添加,所以再增加判断条件,修改为

fishList.set(j, Math.max(j > 0 && (cats_levels.get(j) > cats_levels.get(j - 1)) ? fishList.get(j - 1) + 1 : 1,
                         j < n - 1 && (cats_levels.get(j) > cats_levels.get(j + 1)) ? fishList.get(j + 1) + 1 : 1));

这一次代码便能通过测试,完成题目。

总结反思

这一题主要还是考虑到边界情况,大于小于以及等于的情况的区分考虑。 同时在题目里面使用了AI进行题目内容的分析和解答,但是发现其中存在的一些问题。但是通过看AI的代码能够让我理解到直接进行+1操作来保证最小和符合条件。 因此对于AI提供的内容我们需要保持着独立思考的方式来看待,要结合自己的思考,获得对自己有用的东西。