最大战力值题解 | 豆包MarsCode AI刷题

121 阅读5分钟

题目描述

小F正在设计一款手游,游戏中的角色战力值需要根据一定规则来平衡,以提升玩家的游戏体验。现在游戏中有 ( n ) 个角色,编号从 0 到 ( n-1 )。为了保证平衡性,角色战力值需要遵循以下规则:

  1. 编号为 0 的角色战力值初始为 0。
  2. 每个角色的战力值必须是非负整数。
  3. 相邻角色的战力值差不能超过 1,即两个相邻角色的战力值差可以是 0、+1 或 -1。
  4. 游戏策划还为某些角色设定了最大战力值。这些限制通过若干数对给出,每一个数对 limit[i] = [index, maxPower],表示编号为 index 的角色的战力值不能超过 maxPower。这些限定只会对编号不为 0 的角色生效。

你的任务是根据上述规则和限制,计算游戏中单个角色能达到的最大战力值。

示例

  • 输入:( n = 3 ), ( m = 2 ), limit = [[1, 3], [2, 2]]
    • 输出:2
  • 输入:( n = 5 ), ( m = 3 ), limit = [[1, 1], [2, 3], [4, 3]]
    • 输出:3
  • 输入:( n = 4 ), ( m = 1 ), limit = [[2, 2]]
    • 输出:3

解题思路

分析需求

  • 输入:三个参数,分别是角色数量 ( n ),限制条件数量 ( m ),以及一个二维数组 limit,表示每个角色的最大战力值限制。
  • 输出:一个整数,表示游戏中单个角色能达到的最大战力值。

关键点

  1. 初始化战力值限制:创建一个数组 maxLimits,用于存储每个角色的最大战力值限制。初始时,所有角色的最大战力值限制设置为 Integer.MAX_VALUE,表示没有限制。
  2. 设置初始位置战力值:编号为 0 的角色战力值初始为 0。
  3. 应用限制条件:根据 limit 数组,更新每个角色的最大战力值限制。
  4. 确保相邻角色战力值差不超过 1
    • 从左向右遍历,确保每个角色的战力值不超过前一个角色的战力值加 1。
    • 从右向左遍历,确保每个角色的战力值不超过后一个角色的战力值加 1。
  5. 找出最大战力值:遍历 maxLimits 数组,找到其中的最大值。

算法步骤

  1. 初始化:创建数组 maxLimits 并设置初始值。
  2. 设置初始位置战力值maxLimits[0] = 0
  3. 应用限制条件:遍历 limit 数组,更新 maxLimits
  4. 从左向右遍历:确保相邻角色战力值差不超过 1。
  5. 从右向左遍历:确保相邻角色战力值差不超过 1。
  6. 找出最大战力值:遍历 maxLimits,找到最大值。

代码解析

public class Main {

    public static int solution(int n, int m, int[][] limit) {
        // 创建数组存储每个位置的最大战力值限制
        int[] maxLimits = new int[n];
        for (int i = 0; i < n; i++) {
            maxLimits[i] = Integer.MAX_VALUE;
        }
        
        // 设置初始位置战力值为0
        maxLimits[0] = 0;
        
        // 设置限制条件
        for (int[] l : limit) {
            maxLimits[l[0]] = Math.min(maxLimits[l[0]], l[1]);
        }
        
        // 从左向右遍历,确保相邻差值不超过1
        for (int i = 1; i < n; i++) {
            maxLimits[i] = Math.min(maxLimits[i], maxLimits[i-1] + 1);
        }
        
        // 从右向左遍历,确保相邻差值不超过1
        for (int i = n-2; i >= 0; i--) {
            maxLimits[i] = Math.min(maxLimits[i], maxLimits[i+1] + 1);
        }
        
        // 找出最大战力值
        int maxPower = 0;
        for (int power : maxLimits) {
            maxPower = Math.max(maxPower, power);
        }
        
        return maxPower;
    }

    public static void main(String[] args) {
        // 添加测试用例
        System.out.println(solution(3, 2, new int[][]{{1, 3}, {2, 2}}) == 2);
        System.out.println(solution(5, 3, new int[][]{{1, 1}, {2, 3}, {4, 3}}) == 3);
        System.out.println(solution(4, 1, new int[][]{{2, 2}}) == 3);
    }
}
  • 初始化战力值限制:创建数组 maxLimits 并设置初始值。
  • 设置初始位置战力值maxLimits[0] = 0
  • 应用限制条件:遍历 limit 数组,更新 maxLimits
  • 从左向右遍历:确保相邻角色战力值差不超过 1。
  • 从右向左遍历:确保相邻角色战力值差不超过 1。
  • 找出最大战力值:遍历 maxLimits,找到最大值。

学习心得

1. 理解问题的本质

在解决这个问题时,首先要理解问题的本质,即如何在满足相邻角色战力值差不超过1的前提下,最大化每个角色的战力值。通过明确这一点,我们可以更容易地设计算法来解决问题。

2. 初始化和限制条件的处理

初始化数组 maxLimits 并设置初始值是非常重要的一步。通过将初始值设置为 Integer.MAX_VALUE,我们可以确保后续的限制条件能够正确地更新数组中的值。同时,设置编号为0的角色战力值为0,这是问题的一个关键条件。

3. 双向遍历的必要性

从左向右和从右向左两次遍历数组,确保相邻角色战力值差不超过1,是解决这个问题的关键步骤。通过双向遍历,我们可以确保每个角色的战力值既不会超过其最大限制,又会尽可能接近最大限制。

4. 数据结构的选择

选择合适的数据结构可以简化问题的解决过程。在这个问题中,我们使用了一个数组 maxLimits 来存储每个角色的最大战力值限制。这种做法不仅简单明了,而且效率高。

5. 测试用例的重要性

编写测试用例可以帮助我们验证算法的正确性。在这个问题中,我们提供了几个典型的测试用例,确保我们的算法能够处理各种边界情况。通过这些测试用例,我们可以及时发现和修复潜在的问题。

总结

通过解决这个问题,我深刻体会到了算法设计的重要性。合理的算法设计不仅可以提高程序的效率,还可以使代码更加清晰和易于维护。同时,我也学会了如何通过初始化和限制条件的处理,以及双向遍历来优化算法,这对于解决复杂问题非常有帮助。在未来的学习和工作中,我会继续努力提升自己的算法能力,以应对更多挑战。