likes
comments
collection
share

夯实算法-跳跃游戏

作者站长头像
站长
· 阅读数 52

题目:LeetCode

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

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

判断你是否能够到达最后一个下标。

示例 1:

输入: nums = [2,3,1,1,4]
输出: true
解释: 可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

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

提示:

  • 1 <= nums.length <= 3

解题思路

记数组长度是nnn,从前往后跳,每一步,下标iii可以跳的最大长度是其元素[i][i][i],意思就是每一步都有若干选择,可以跳 000,也可以跳[i][i][i],问能否到达最后一个下标 n−1n-1n1,很明显可以用动态规划解决。

状态转移方程是结果导向,换句话说就是要尽可能的以直接得到最终结果来定义状态。

f(i)f(i)f(i)为能否跳跃到下标为 iii 的状态,那么 f(n−1)f(n-1)f(n1) 就是整个问题的解。

如果从i−1i−1i1位置跳,那么只要[i−1][i−1][i1]大于等于111,并且f(i−1)f(i−1)f(i1)也是TTT,就能达到位置iii;同理,如果从i−2i−2i2位置跳,只要[i−2][i−2][i2]大于等于222,并且f(i−2)f(i−2)f(i2)TTT即可,

可得到状态转移方程: f(i)=f(j)∧nums[j]≥i−j,j∈[0,i−1]f(i)=f(j)∧nums[j]≥i−j,j∈[0,i−1]f(i)=f(j)nums[j]ij,j[0,i1]

且明显f(0)=Tf(0)=Tf(0)=T

代码实现

public boolean canJump(int[] nums) {
    final int n = nums.length;
    boolean[] dp = new boolean[n];
    dp[0] = true;
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (dp[j] && nums[j] >= i - j) {
                dp[i] = true;
            }
        }
    }
    return dp[n - 1];
}

复杂度分析

  • 空间复杂度:O(1)O(1)O(1)
  • 时间复杂度:O(n2)O(n^2)O(n2)
转载自:https://juejin.cn/post/7173685239884677150
评论
请登录