55. 跳跃游戏(leetcode)

https://leetcode.cn/problems/jump-game/

此题有部分贪心思想,可以从前面状态快速判断后面状态是否可行

class Solution {
    public boolean canJump(int[] nums) {
        // 1e4 o(n^2)以内
        // 考虑能否使用dp,判断递推思路有无后效性
        // f[i] 表示能否跳到i位置
        // 以i最后一步从哪跳过来的为标准推导,从哪一步跳过来的坐标是一个序列,位置定为nums[k]
        // f[i] = f[i-1] || f[i-2] || ... || f[i-k], nums[k~(i-1)] >= k ,i > k >=0
        // 初值边界条件
        // f[0] = true
        // ans = f[nums.length-1]

//        boolean[] f = new boolean[nums.length];
//        f[0]=true;
//        for(int i=1;i<nums.length;i++) {
//            for(int k=0;k<i;k++) {
//                if(nums[k] >= i-k) {
//                    // k位置可以跳到i位置
//                    f[i] = f[i] || f[k];
//                }
//            }
//        }
//        return f[nums.length-1];
        // f[i] 还可以定义为,前i个节点能跳到的最大距离,这样状态计算就不用像上面枚举k序列了
        // 明显方程具有后效性,可以从上一步推导到当前第i步,无需划分集合
        // f[i] = max(f[i-1],i+nums[i]);
        // ans = f[nums.length-1] >= nums.length-1
        // 初值边界条件
        // f[0] = nums[0]
//        int[] f = new int[nums.length];
//        f[0] = nums[0];
//        for(int i=1;i<nums.length;i++) {
//            if(f[i-1] < i) {
//                // 前i-1个节点都不能跳到第i个位置,此时无法跳到最后一个位置,直接放弃
//                return false;
//            }
//            f[i] = Math.max(f[i-1],i+nums[i]);
//        }
//        // 前面节点能跳的最远距离 >= 最后一个节点
//        return true;

        // 由于状态只依赖上一层,因此可以优化一个维度
        int f = nums[0];
        for(int i=1;i<nums.length;i++) {
            if(f < i) {
                // 前i-1个节点都不能跳到第i个位置,此时无法跳到最后一个位置,直接放弃
                return false;
            }
            f = Math.max(f,i+nums[i]);
        }
        return true;
    }
}

 

posted @ 2026-02-09 10:03  风乐  阅读(12)  评论(0)    收藏  举报