跳跃游戏 VIII
难度:
标签:
题目描述
代码结果
运行时间: 218 ms, 内存: 32.2 MB
/*
题目:跳跃游戏 VIII
题目编号:2297
题目描述:给定一个数组,表示每个位置可以跳跃的最大步数,判断是否可以从第一个位置跳到最后一个位置。
思路:
1. 使用IntStream来遍历数组。
2. 用AtomicInteger来记录最远可达位置。
3. 在遍历过程中,更新最远可达位置。
4. 如果最远可达位置大于等于最后一个位置,则返回true。
*/
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
public class JumpGameVIIIStream {
public boolean canJump(int[] nums) {
AtomicInteger maxReach = new AtomicInteger(0);
return IntStream.range(0, nums.length).allMatch(i -> {
if (i > maxReach.get()) {
return false;
}
maxReach.set(Math.max(maxReach.get(), i + nums[i]));
return maxReach.get() >= nums.length - 1 || i < nums.length - 1;
});
}
public static void main(String[] args) {
JumpGameVIIIStream solution = new JumpGameVIIIStream();
int[] nums = {2, 3, 1, 1, 4};
System.out.println(solution.canJump(nums)); // 输出 true
}
}
解释
方法:
题解使用了动态规划和单调栈的结合来解决问题。动态规划数组 `dp[i]` 代表从起点到达点 `i` 的最小成本。解决思路是遍历每一个位置 `i`,并维护两个单调栈:`maxStk` 和 `minStk`。`maxStk` 维护一个单调递减的栈,其中 `nums` 的值是递减的;当遇到一个比栈顶更大的元素时,我们从栈顶移除元素,并更新 `dp[i]`。类似地,`minStk` 维护一个单调递增的栈,用于处理当前元素比栈顶元素小的情况。通过这种方式,我们能够在遍历数组的同时,快速找到之前的位置 `k`,使得从 `k` 到 `i` 的转移成本最小,即 `dp[i] = min(dp[i], dp[k] + cost[i])`。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在解题中,为何选择使用单调栈结合动态规划而不是仅使用动态规划或其他数据结构?
▷🦆
单调栈在这种情况下如何具体帮助减少计算量,能否详细解释它是如何优化状态转移方程的计算的?
▷🦆
题解中提到单调递增栈和单调递减栈同时维护,这种做法在解决问题中起到了什么作用,它们各自又是如何影响dp数组的更新的?
▷