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

73 阅读4分钟

问题分析

在猫星球上,小R需要根据一组猫的等级,公平地分配鱼干。每只猫的等级决定了它所需鱼干的数量,等级越高的猫应该获得更多的鱼干。我们需要保证以下几点:

  1. 每只猫至少得到一斤鱼干:这是分配鱼干的基本要求,无论猫的等级如何,每只猫都必须至少获得一斤鱼干。
  2. 等级较高的猫应得到更多的鱼干:如果一只猫的等级高于相邻的猫,那么它就应当得到比相邻猫更多的鱼干。这个规则要求我们考虑猫之间等级的相对关系。

思路分析

为了解决这个问题,我们需要:

  1. 初始化一个鱼干分配数组:我们首先初始化每只猫至少得到1斤鱼干。
  2. 从左到右遍历:如果当前猫的等级高于前一只猫,则当前猫应该比前一只猫得到更多的鱼干。
  3. 从右到左遍历:为了确保符合“相邻猫之间等级较高的猫鱼干更多”的条件,我们还需要从右到左进行一次遍历,如果当前猫的等级高于后一只猫,并且鱼干数不满足要求,则增加鱼干数。
  4. 求总鱼干数量:最后,我们将所有猫得到的鱼干数加起来,得到总的鱼干需求量。

解决方案

我们使用一个数组fish来记录每只猫的鱼干分配情况。初始时,每只猫都分配1斤鱼干。然后,我们从左到右扫描猫的等级,如果当前猫的等级高于前一只猫,则当前猫的鱼干数应该比前一只猫多1斤。接着,从右到左扫描猫的等级,确保每只猫的鱼干数符合条件。

具体的步骤如下:

  1. 初始化数组:初始化一个fish数组,长度与猫的数量n相同,所有元素都为1。
  2. 左到右遍历:如果某只猫的等级高于它前面的猫,则它的鱼干数应该比前一只猫多1。
  3. 右到左遍历:如果某只猫的等级高于它后面的猫,并且它的鱼干数没有满足要求,则需要更新它的鱼干数,保证它比后面的猫多1斤。
  4. 计算总鱼干:遍历fish数组,求出所有猫所需的鱼干总和。

代码实现

#include <iostream>
#include <vector>

int solution(int n, std::vector<int> catsLevels) {
    // 初始化一个数组来存储每只猫分配的鱼干数量,初始值都为 1
    std::vector<int> fish(n, 1); 
    
    // 从左到右遍历猫的等级数组
    for (int i = 1; i < n; ++i) { 
        if (catsLevels[i] > catsLevels[i - 1]) { 
            fish[i] = fish[i - 1] + 1; 
        }
    }
    
    // 从右到左再次遍历猫的等级数组
    for (int i = n - 2; i >= 0; --i) { 
        if (catsLevels[i] > catsLevels[i + 1] && fish[i] <= fish[i + 1]) { 
            fish[i] = fish[i + 1] + 1; 
        }
    }
    
    // 计算并返回鱼干总数
    int totalFish = 0; 
    for (int f : fish) { 
        totalFish += f; 
    }
    return totalFish;
}

int main() {
    std::vector<int> catsLevels1 = {1, 2, 2};
    std::vector<int> catsLevels2 = {6, 5, 4, 3, 2, 16};
    std::vector<int> catsLevels3 = {1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4};
    
    std::cout << (solution(3, catsLevels1) == 4) << std::endl; // 输出: 4
    std::cout << (solution(6, catsLevels2) == 17) << std::endl; // 输出: 17
    std::cout << (solution(20, catsLevels3) == 35) << std::endl; // 输出: 35
    
    return 0;
}

代码讲解

  1. solution函数:这个函数接收两个参数,一个是猫的数量n,另一个是猫的等级数组catsLevels。我们用一个fish数组来存储每只猫的鱼干数,初始值为1。通过两次遍历,分别从左到右和右到左,确保每只猫的鱼干数符合条件。
  2. 左到右遍历:在左到右的遍历中,若catsLevels[i] > catsLevels[i - 1],则fish[i]应当比fish[i - 1]多1。
  3. 右到左遍历:在右到左的遍历中,若catsLevels[i] > catsLevels[i + 1]fish[i] <= fish[i + 1],则fish[i]应当比fish[i + 1]多1。
  4. 最终计算总鱼干:我们将fish数组中所有元素的值相加,得到所有猫所需的鱼干总数。

示例解释

以第一个示例catsLevels = [1, 2, 2]为例:

  • 初始化时,每只猫得到1斤鱼干,fish = [1, 1, 1]
  • 左到右遍历时,第二只猫的等级高于第一只猫,因此第二只猫得到2斤鱼干,fish = [1, 2, 1]
  • 右到左遍历时,第三只猫的等级与第二只猫相同,不需要更改。
  • 最终,所有猫的鱼干数为[1, 2, 1],总共需要1 + 2 + 1 = 4斤鱼干。

复杂度分析

  • 时间复杂度:两次遍历猫的等级数组,因此时间复杂度是O(n),其中n是猫的数量。
  • 空间复杂度:我们使用了一个额外的fish数组来存储每只猫的鱼干数,因此空间复杂度是O(n)。

通过上述分析和实现,我们可以高效地解决这个问题,并计算出小R需要准备的最少鱼干数量。