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

75 阅读4分钟

问题描述

在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:

  1. 每只猫至少得到一斤鱼干。
  2. 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。

小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。

思路分析

  1. 问题本质

    • 需要确保每只猫的鱼干数量满足两个条件:每只猫至少得到一斤鱼干,且如果猫的等级高于相邻的猫,它应该得到更多的鱼干。
    • 使用两次遍历的贪心算法来解决这个问题。第一次从左到右遍历,确保每只猫的鱼干数量不小于它左边的猫。第二次从右到左遍历,确保每只猫的鱼干数量不小于它右边的猫。
  2. 解决方案

    • 初始化鱼干数组:所有猫的初始鱼干数量都设为1。
    • 第一次遍历:从左到右遍历,如果当前猫的等级高于左边的猫,更新当前猫的鱼干数量为左边猫的鱼干数量加1。
    • 第二次遍历:从右到左遍历,如果当前猫的等级高于右边的猫,更新当前猫的鱼干数量为右边猫的鱼干数量加1,并取两者中的最大值。
    • 计算总鱼干数量:遍历鱼干数组,计算所有猫的鱼干总数。

代码详解


import java.util.ArrayList;
import java.util.List;

public class Main {
    public static int solution(int n, List<Integer> cats_levels) {
        // 初始化鱼干数组,每只猫至少得到一斤鱼干
        int[] fish = new int[n];
        for (int i = 0; i < n; i++) {
            fish[i] = 1;
        }

        // 从左到右遍历,确保每只猫的鱼干数量正确
        for (int i = 1; i < n; i++) {
            if (cats_levels.get(i) > cats_levels.get(i - 1)) {
                fish[i] = fish[i - 1] + 1;
            }
        }

        // 从右到左遍历,确保每只猫的鱼干数量正确
        for (int i = n - 2; i >= 0; i--) {
            if (cats_levels.get(i) > cats_levels.get(i + 1)) {
                fish[i] = Math.max(fish[i], fish[i + 1] + 1);
            }
        }

        // 计算总鱼干数量
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += fish[i];
        }
        return sum;
    }

    public static void main(String[] args) {
        List<Integer> catsLevels1 = new ArrayList<>();
        catsLevels1.add(1);
        catsLevels1.add(2);
        catsLevels1.add(2);

        List<Integer> catsLevels2 = new ArrayList<>();
        catsLevels2.add(6);
        catsLevels2.add(5);
        catsLevels2.add(4);
        catsLevels2.add(3);
        catsLevels2.add(2);
        catsLevels2.add(16);

        List<Integer> catsLevels3 = new ArrayList<>();
        catsLevels3.add(1);
        catsLevels3.add(2);
        catsLevels3.add(2);
        catsLevels3.add(3);
        catsLevels3.add(3);
        catsLevels3.add(20);
        catsLevels3.add(1);
        catsLevels3.add(2);
        catsLevels3.add(3);
        catsLevels3.add(3);
        catsLevels3.add(2);
        catsLevels3.add(1);
        catsLevels3.add(5);
        catsLevels3.add(6);
        catsLevels3.add(6);
        catsLevels3.add(5);
        catsLevels3.add(5);
        catsLevels3.add(7);
        catsLevels3.add(7);
        catsLevels3.add(4);

        System.out.println(solution(3, catsLevels1) == 4);
        System.out.println(solution(6, catsLevels2) == 17);
        System.out.println(solution(20, catsLevels3) == 35);
    }
}

知识总结

  1. 贪心算法

    • 贪心算法是一种在每个步骤中都选择当前最优解的算法,适用于某些特定的优化问题。
    • 在这个问题中,通过两次遍历(从左到右和从右到左)来确保每只猫的鱼干数量满足条件,是一种典型的贪心算法应用。
  2. 字符频次统计

    • 这个问题没有涉及字符频次统计,但可以通过类似的逻辑来解决问题,即逐步更新每个元素的值,确保满足特定的条件。
  3. 条件判断

    • 使用 if 语句来检查猫的等级是否高于相邻的猫,确保鱼干数量的更新符合规则。
    • 通过 Math.max 函数来取两个值中的最大值,确保鱼干数量满足从左到右和从右到左的条件。
  4. 代码优化

    • 通过使用数组 fish 来记录每只猫的鱼干数量,可以提高代码的执行效率。
    • 在 main 函数中添加更多的测试用例,确保代码的正确性和鲁棒性。

个人理解与学习建议

  1. 理解贪心算法

    • 贪心算法是一种非常实用的算法,通过在每个步骤中选择当前最优解,可以高效地解决某些优化问题。
    • 通过这个题目,可以加深对贪心算法的理解,学会如何在实际问题中应用。
  2. 代码可读性

    • 使用有意义的变量名,如 fishcats_levels 等,可以提高代码的可读性。
    • 添加注释,解释每一步的逻辑,有助于他人理解代码。
  3. 测试用例

    • 在 main 函数中添加更多的测试用例,确保代码的正确性和鲁棒性。
    • 测试用例应涵盖各种边界情况和特殊输入,确保代码在所有情况下都能正确运行。
  4. 学习建议

    • 多做练习:通过多做类似的题目,可以提高对贪心算法的理解和应用能力。
    • 思考边界情况:在编写代码时,思考各种边界情况,确保代码的鲁棒性。
    • 代码模块化:将代码分成多个函数或模块,可以提高代码的可维护性和可读性。