小哆啦的最小跳跃冒险
小哆啦开始力扣每日一题的第七天
开始旅程:蛮力初探
小哆啦是一只爱冒险的哆啦A梦,他发现了一片神秘的数字世界。这片世界是一条由整数构成的道路,每个数字代表他在当前位置能跳跃的最大距离。他的任务是找到到达道路尽头的最小跳跃次数。
小哆啦的蛮力方法
“既然每个位置都能跳不同的步数,那我就尝试从每个点出发,探索所有可能的跳跃方式吧!”小哆啦带着这个想法,写下了他的第一版代码:
function jump(nums: number[]): number {
const n = nums.length;
let minJumps = Infinity;
function dfs(index: number, jumps: number): void {
if (index >= n - 1) {
minJumps = Math.min(minJumps, jumps);
return;
}
for (let step = 1; step <= nums[index]; step++) {
dfs(index + step, jumps + 1);
}
}
dfs(0, 0);
return minJumps;
}
console.log(jump([2, 3, 1, 1, 4])); // 输出:2
这段代码让小哆啦尝试了所有的跳跃路径。但很快,他就发现了问题:“这种方法太慢了!每个位置都要递归地探索所有可能,数字多一点,我的脑袋就要烧坏了!”
优化一:动态规划的智慧
小哆啦想起了自己的时间机器和竹蜻蜓,他决定从未来带回一个优化的想法——动态规划。他对自己说:“如果我已经知道从某个点到终点需要的最少跳跃次数,那么我就可以逆向计算出其他位置的答案!”
他快速实现了第二版代码:
function jump(nums: number[]): number {
const n = nums.length;
const dp = Array(n).fill(Infinity);
dp[0] = 0;
for (let i = 0; i < n; i++) {
for (let j = 1; j <= nums[i] && i + j < n; j++) {
dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
}
}
return dp[n - 1];
}
console.log(jump([2, 3, 1, 1, 4])); // 输出:2
这一次,小哆啦满意地微笑了。“终于快了很多!”他感叹道,“不过,还是有点慢,能不能再快一点呢?”
终极优化:贪心法的点拨
在一次散步中,小哆啦遇见了哆啦小红,她是一个贪心策略的专家。小红告诉他:“如果你总是尽可能跳得更远,那你就可以更快到达终点。没必要每一步都记住所有可能!”
受到启发的小哆啦,迅速优化了代码:
function jump(nums: number[]): number {
let jumps = 0;
let currentEnd = 0;
let farthest = 0;
for (let i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, i + nums[i]);
if (i === currentEnd) {
jumps++;
currentEnd = farthest;
}
}
return jumps;
}
console.log(jump([2, 3, 1, 1, 4])); // 输出:2
胜利的终点
小哆啦运行了这段代码,发现它飞快地完成了任务。“哈哈,终于到达了终点!而且是用最少的跳跃次数!”
他总结道:“从尝试所有可能,到使用动态规划的智慧,再到贪心策略的点拨,我终于掌握了这片数字世界的规则。这次冒险真是太棒了!”
小哆啦带着满满的成就感,继续踏上了下一个未知的旅程……