zoukankan      html  css  js  c++  java
  • LeetCode——55. 跳跃游戏

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

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

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

    示例 1:

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

    示例 2:

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

    动态规划

    这里可以用动态规划 Dynamic Programming 来解,维护一个一维数组 dp,其中 dp[i] 表示达到i位置时剩余的跳力,若到达某个位置时跳力为负了,说明无法到达该位置。

    接下来难点就是推导状态转移方程,到达当前位置的剩余跳力,其实是跟上一个位置的剩余跳力(dp 值)和上一个位置新的跳力(nums 数组中的值)有关,这里新的跳力就是原数组中每个位置的数字,因为其代表了以当前位置为起点能到达的最远位置。

    所以当前位置的剩余跳力(dp 值)和当前位置新的跳力中的较大那个数决定了当前能到的最远距离,而下一个位置的剩余跳力(dp 值)就等于当前的这个较大值减去1,因为需要花一个跳力到达下一个位置,所以就有状态转移方程了:dp[i] = max(dp[i - 1], nums[i - 1]) - 1,如果当某一个时刻 dp 数组的值为负了,说明无法抵达当前位置,则直接返回 false,最后循环结束后直接返回 true 即可,参见代码如下:

    c++

    class Solution {
    public:
        bool canJump(vector<int>& nums) {
            vector<int> dp(nums.size(), 0);
            for (int i = 1; i < nums.size(); ++i) {
                dp[i] = max(dp[i - 1], nums[i - 1]) - 1;
                if (dp[i] < 0) return false;
            }
            return true;
        }
    };
    

    java

    class Solution {
        public boolean canJump(int[] nums) {
            int[] dp = new int[nums.length];
            for(int i = 1; i < nums.length; ++i){
                dp[i] = Math.max(dp[i-1], nums[i-1]) - 1;
                if (dp[i] < 0) return false;
            }
            return true;
        }
    }
    

    贪婪算法

    这里并不是很关心每一个位置上的剩余步数,而只希望知道能否到达末尾,也就是说我们只对最远能到达的位置感兴趣,所以维护一个变量 reach,表示最远能到达的位置,初始化为0。

    遍历数组中每一个数字,如果当前坐标大于 reach 或者 reach 已经抵达最后一个位置则跳出循环,否则就更新 reach 的值为其和 i + nums[i] 中的较大值,其中 i + nums[i] 表示当前位置能到达的最大位置,参见代码如下:

    c++

    class Solution {
    public:
        bool canJump(vector<int>& nums) {
            int n = nums.size(), reach = 0;
            for (int i = 0; i < n; ++i) {
                if (i > reach || reach >= n - 1) break;
                reach = max(reach, i + nums[i]);
            }
            return reach >= n - 1;
        }
    };
    

    java

    public class Solution {
        public boolean canJump(int[] nums) {
            int lastPos = nums.length - 1;
            for (int i = nums.length - 1; i >= 0; i--) {
                if (i + nums[i] >= lastPos) {
                    lastPos = i;
                }
            }
            return lastPos == 0;
        }
    }
    

    python

    class Solution:
        def canJump(self, nums) :
            max_i = 0                          #初始化当前能到达最远的位置
            for i, jump in enumerate(nums):    #i为当前位置,jump是当前位置的跳数
                if max_i>=i and i+jump>max_i:  #如果当前位置能到达,并且当前位置+跳数>最远位置  
                    max_i = i+jump             #更新最远能到达位置
            return max_i>=i
    
  • 相关阅读:
    PHP保留小数的相关方法
    ASP.NET Core MVC 之过滤器(Filter)
    ASP.NET Core MVC 之控制器(Controller)
    ASP.NET Core MVC 之视图组件(View Component)
    ASP.NET Core MVC 之局部视图(Partial Views)
    标签助手(TagHelper)
    ASP.NET Core MVC 之布局(Layout)
    ASP.NET Core MVC 之视图(Views)
    ASP.NET Core MVC 之模型(Model)
    九卷读书:淘宝从小到大的发展 -重读《淘宝技术这十年》
  • 原文地址:https://www.cnblogs.com/wwj99/p/12394843.html
Copyright © 2011-2022 走看看