1. 问题背景与理解
LeetCode 403题"青蛙过河"是一个经典的动态规划问题。题目描述一只青蛙想要过河,河中有若干石头,青蛙从第一块石头出发,每次跳跃的距离只能是前一次跳跃距离的k-1、k或k+1(k为前一次跳跃距离)。我们需要判断青蛙是否能够成功到达最后一块石头。
这个问题的实际应用场景很广泛,比如在机器人路径规划、游戏AI设计等领域都有类似的需求。理解这个问题的关键在于把握"跳跃距离只能在前一次基础上±1"这个约束条件。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路分析
2.1 暴力解法与优化方向
最直观的解法是使用深度优先搜索(DFS)尝试所有可能的跳跃路径。但这种方法的复杂度会随着石头数量呈指数级增长,显然不适合大规模输入。
优化方向主要有两个:
- 记忆化搜索:记录已经计算过的状态,避免重复计算
- 动态规划:系统地构建状态转移关系
2.2 动态规划状态定义
我们定义dp[i][k]表示青蛙能否通过k步跳跃到达第i块石头。其中:
- i是石头的索引
- k是到达i时的跳跃步数
状态转移方程为:
对于每块石头i,检查所有可能的j < i,如果stones[i] - stones[j] == k,且dp[j][k-1]、dp[j][k]或dp[j][k+1]中任意一个为true,则dp[i][k] = true。
3. 代码实现详解
3.1 基础数据结构选择
使用HashMap来存储石头位置到索引的映射,方便快速查找:
java复制Map<Integer, Integer> stonePositions = new HashMap<>();
for (int i = 0; i < stones.length; i++) {
stonePositions.put(stones[i], i);
}
3.2 动态规划表初始化
使用二维布尔数组dp,其中dp[i][k]表示能否以k步跳到第i块石头:
java复制boolean[][] dp = new boolean[n][n];
dp[0][0] = true; // 初始状态:在第0块石头,跳跃步数为0
3.3 状态转移实现
核心状态转移逻辑:
java复制for (int i = 1; i < n; i
