题目描述
小F正在设计一款手游,游戏中的角色战力值需要根据一定规则来平衡,以提升玩家的游戏体验。现在游戏中有 ( n ) 个角色,编号从 0 到 ( n-1 )。为了保证平衡性,角色战力值需要遵循以下规则:
- 编号为 0 的角色战力值初始为 0。
- 每个角色的战力值必须是非负整数。
- 相邻角色的战力值差不能超过 1,即两个相邻角色的战力值差可以是 0、+1 或 -1。
- 游戏策划还为某些角色设定了最大战力值。这些限制通过若干数对给出,每一个数对
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,表示每个角色的最大战力值限制。 - 输出:一个整数,表示游戏中单个角色能达到的最大战力值。
关键点
- 初始化战力值限制:创建一个数组
maxLimits,用于存储每个角色的最大战力值限制。初始时,所有角色的最大战力值限制设置为Integer.MAX_VALUE,表示没有限制。 - 设置初始位置战力值:编号为 0 的角色战力值初始为 0。
- 应用限制条件:根据
limit数组,更新每个角色的最大战力值限制。 - 确保相邻角色战力值差不超过 1:
- 从左向右遍历,确保每个角色的战力值不超过前一个角色的战力值加 1。
- 从右向左遍历,确保每个角色的战力值不超过后一个角色的战力值加 1。
- 找出最大战力值:遍历
maxLimits数组,找到其中的最大值。
算法步骤
- 初始化:创建数组
maxLimits并设置初始值。 - 设置初始位置战力值:
maxLimits[0] = 0。 - 应用限制条件:遍历
limit数组,更新maxLimits。 - 从左向右遍历:确保相邻角色战力值差不超过 1。
- 从右向左遍历:确保相邻角色战力值差不超过 1。
- 找出最大战力值:遍历
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. 测试用例的重要性
编写测试用例可以帮助我们验证算法的正确性。在这个问题中,我们提供了几个典型的测试用例,确保我们的算法能够处理各种边界情况。通过这些测试用例,我们可以及时发现和修复潜在的问题。
总结
通过解决这个问题,我深刻体会到了算法设计的重要性。合理的算法设计不仅可以提高程序的效率,还可以使代码更加清晰和易于维护。同时,我也学会了如何通过初始化和限制条件的处理,以及双向遍历来优化算法,这对于解决复杂问题非常有帮助。在未来的学习和工作中,我会继续努力提升自己的算法能力,以应对更多挑战。