石子游戏 VIII
难度:
标签:
题目描述
代码结果
运行时间: 131 ms, 内存: 27.4 MB
/**
* 思路:
* 使用动态规划和 Java Stream API 来解决问题。
* 我们依然使用前缀和数组 prefixSums 来计算区间和。
* 通过 streams 来遍历和计算 dp 数组。
*/
import java.util.stream.IntStream;
public class StoneGameStream {
public int stoneGameVII(int[] stones) {
int n = stones.length;
int[] prefixSums = IntStream.rangeClosed(1, n)
.map(i -> IntStream.of(stones).limit(i).sum())
.toArray();
int[][] dp = new int[n][n];
IntStream.range(2, n + 1).forEach(length ->
IntStream.range(0, n - length + 1).forEach(i -> {
int j = i + length - 1;
dp[i][j] = Math.max(prefixSums[j + 1] - prefixSums[i + 1] - dp[i + 1][j],
prefixSums[j] - prefixSums[i] - dp[i][j - 1]);
})
);
return dp[0][n - 1];
}
}
解释
方法:
这道题解的思路是动态规划。首先,通过累加前缀和,将stones数组转换为存储从第一个石头到当前位置所有石头的总和。接着,从数组末尾向前遍历,计算每个位置可以给后手带来的最小分差。具体来说,对于每个位置j,计算当Alice到达该位置时,如果接下来由Bob开始,他们分数差的最优解。这是通过取当前位置的前缀和减去之前位置得到的最大收益来计算的。通过这种方式,递推得到最终的结果。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到的前缀和数组是如何帮助理解和解决这个问题的?
▷🦆
动态规划的转移方程是怎样的,可以详细解释一下吗?
▷🦆
为什么动态规划的过程中需要从数组的末尾向前遍历?
▷🦆
在题解中提到,更新当前最大分差 `curmax` 时使用的条件是 `profit > curmax`,这样的更新逻辑是如何确保最终结果是最优的?
▷