(LeetCode一刷)动态规划-跳跃游戏问题

注:个人算法比较菜,由于是第一遍刷题,代码质量可能都不好,这里暂时做个刷题记录:)。

问题描述:

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

示例 1:

输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:

输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvb8zs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分析:

最优子结构:
1、倒数第i个可以直达
2、倒数第i个不可以直达

边界:
i =0 || i=1

状态转移方程式:
倒数第i个可以直达
arr[i]>=len-1-i
f(i)=f(i-1) //自顶向下迭代
倒数第i个不可直达
arr[i]<len-1-i
g(i)=g(i-1) //自顶向下迭代

代码求解:

1、递归方式求解

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var canJump1 = function(nums) {
    if(nums.length===0) return false; //传入的数组为空,则返回false
    if(nums.length===1) return true; //数组只有一个元素,返回true
    var len = nums.length;
    if(nums[len-2]>=1){//若倒数第一个可以到达最后位置,则问题转化成长度为len-1的数组是否可以达到最后位置
       return canJump1(nums.slice(0, len-1));
    }else{//判断倒数第二个能否直达
        for(var i=len-3; i>=0; i--){
            if(nums[i]>=len-1-i){
               if(i===0) return true;
               return canJump1(nums.slice(0, i+1));
            }
        }
        return false;
    }
};

经测试性能不过关,数组长度为10000个会报内存溢出错误。

2、采用自顶向下的方式求解。

var canJump = function(nums){
    if(nums.length===0) return false;
    if(nums.length===1) return true;
    
    var len = nums.length;
    var index = len-1; //记住能够直达目标位置的数组索引
    var max = len-1; //记住当前的要到达的目标位置
    for(var i=len-1; i>=0; i--) {//自顶向下迭代
        if(nums[i]>=max-i){//从i到max可达
            index = i;
            max = i;
        }
    }
    return index===0;    //如果第一个元素能到达目标位置,则最后位置是可达的
};

 

 之前看过挖金矿问题的动态规划求解是自底向上的方式,本题没试过是否可行。后续再看看:)

 

posted on 2020-08-23 15:58  DavidXu2014  阅读(424)  评论(0编辑  收藏  举报