382.小C不怕困难 | 豆包MarsCode AI刷题

63 阅读3分钟

在这个有趣的情境中,小 C 遇到了一系列怪物,每个怪物都有特定的战斗力,而小 C 需要根据给定的战斗规则依次与这些怪物战斗,并尝试通过合理安排战斗顺序来使自己在打败所有怪物后累计提升的勇气值达到最大。

一、问题定义

给定整数 n 表示怪物的数量,以及一个整数数组 a,其中 a[i] 表示第 i 个怪物的战斗力,小 C 初始战斗力为 0。战斗规则如下: 当小 C 的战斗力 X 小于怪物的战斗力 a[i] 时,小 C 触发被动技能 “小 C 不怕困难”,将自己的战斗力提升至 a[i],战胜该怪物,同时勇气值增加 a[i] - X。 当小 C 的战斗力 X 大于或等于怪物的战斗力 a[i] 时,小 C 直接战胜怪物,战斗结束后,战斗力降低至 a[i]。 需要找出小 C 在打败所有怪物后能够累计提升的最大勇气值。

二、分析思路

(一)排序思路

采用的思路是先对怪物的战斗力数组 a 进行排序。其核心想法在于,通过排序可以更方便地安排战斗顺序,以获取最大的勇气值提升。具体来说,先打战斗力强的怪物(排序后的数组末尾元素),在小 C 战斗力低时遇到强怪物能触发被动技能获得较多的勇气值提升;然后再打战斗力弱的怪物(排序后的数组开头元素),此时由于前面战斗后战斗力已调整,能顺利战胜弱怪物且不影响整体获取最大勇气值的策略。

三、代码实现

以下是 Java 代码实现:

public static int solution(int n, int[] a) {
    // 对怪物战斗力数组进行排序
    Arrays.sort(a);
    int l = 0;
    int r = a.length - 1;
    int cnt = 0;
    int fight = 0;
    int courage = 0;
    while (r >= l) {
        if (cnt % 2 == 0) { // 先打大的
            courage = courage + a[r] - fight; // 先变勇敢再击败,计算勇气值提升并累加
            fight = a[r];
            r--;
            cnt++;
        } else { // 再打小的
            fight = a[l];
            l++;
            cnt++;
        }
    }

    return courage;
}

在上述代码中: 首先通过 Arrays.sort(a) 对怪物战斗力数组进行排序。 然后使用双指针的方式,通过 l 和 r 分别指向数组的开头和末尾,根据 cnt 的奇偶性来决定是先打大怪物还是小怪物,在打大怪物时计算并累加勇气值提升,打小怪物时调整战斗后的战斗力值。

四、复杂度分析

时间复杂度:

主要的时间消耗在于对数组 a 进行排序,Java 中 Arrays.sort() 方法对于基本数据类型数组的排序时间复杂度通常为 ,其中 n 是数组 a 的长度。而后续的循环遍历操作时间复杂度为 ,但由于 占主导地位,所以整体时间复杂度为 。

空间复杂度:

代码中除了定义了几个常量和指针变量外,没有使用额外的数据结构来存储大量数据,所以空间复杂度为 ,即常数级别的空间占用。

五、总结

通过对怪物战斗力数组进行排序,并按照先打大怪物后打小怪物的策略,能够有效地计算出小 C 在打败所有怪物后可以累计提升的最大勇气值。理解这种根据战斗规则合理安排战斗顺序以及利用排序简化计算的思路,对于解决类似的需要根据特定规则优化操作顺序以达到最优结果的问题具有一定的借鉴意义。同时,分析代码的时间和空间复杂度也有助于我们评估算法在不同场景下的性能表现。