zoukankan      html  css  js  c++  java
  • LeetCode 55. 跳跃游戏(Jump Game)I II tag 数组 贪心 动态规划

    labuladong

    一、

    题目描述

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

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

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

    示例 1:

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

    示例 2:

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

    思路一:
    使用动态规划的想法,用额外的数组记录可以到达的位置,然后通过reach[n-1]来判断
    可以解题,但是速度太慢。
    class Solution {
    public:
        bool canJump(vector<int>& nums) {
            int n=nums.size();
            if(n<2)
                return true;
            vector<bool> reach(n,false);
            reach[0]=true;
            for(int i=0;i<n;++i)
            {
                if(reach[i])
                {
                    for(int j=1;j<=nums[i]&&i+j<n;j++)
                    {
                        reach[i+j]=true;
                    }
                    if(reach[n-1])
                        return true;
                }
            }
            return reach[n-1];
        }
    };
    思路二:
      • 每次到一个位置 i,判断 maxS 最远可到的位置下标能不能到达 i
      • 能到达,则在当前位置可达的最远位置下标为 nums[i] + i , 取其与 maxS 的大者为最远可达位置
      • 循环判断
        在这里插入图片描述
    class Solution {
    public:
        bool canJump(vector<int>& nums) {
             int maxS = 0, i;
             for(i = 0; i < nums.size(); ++i)
             {
                 if(maxS < i)
                     return false;
                 maxS = max(maxS, nums[i]+i);
             }
             return true;
        }
    };
    class Solution {
    public:
        bool canJump(vector<int>& nums) {
            int n=nums.size();
            int maxLen=0;
            for(int i=0;i<n;++i)
            {
                if(i<=maxLen)
                {
                    maxLen=max(maxLen, i+nums[i]);
                    if(maxLen>=n-1)
                        return true;
                }
            }
            return false;
        }
    };
    二、

    题目描述

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

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

    你的目标是使用最少的跳跃次数到达数组的最后一个位置。

    示例:

    输入: [2,3,1,1,4]输出: 2解释: 跳到最后一个位置的最小跳跃数是 2。
    从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
    

    说明:假设你总是可以到达数组的最后一个位置。

    思路:

    这道题的最优解是可以时间复杂度优化到 O(n) 的,那就是采用贪心算法,我们从左边的起点开始跳跃的时候,我们应该跳跃到哪一个点比较合适呢?,显然,每次都跳跃最大长度的话,是不行的。例如对于上面 arr = {2, 3, 1, 1, 4, 2, 1} 这个例子,刚开 arr[0] = 2,那么我们可以跳到 arr[1] = 3 或者 arr[2] = 1 上,显然,我们跳跃 arr[1] = 3 会更好一点。如图(图片来源于网络)

    leetcode 第45题:跳跃游戏2

    接着同样的道理,我们可以从 arr[1] = 3 这个位置开始跳跃,它可以跳跃到 arr[2] = 1, arr[3] = 1, arr[4] = 4 这三个位置,显然,我们跳到 arr[4] = 4 这个位置好一点,如图(图片来源于网络)

    leetcode 第45题:跳跃游戏2

    也就是说,我们要跳跃的那个点,可以使得上一次 + 下一次的跳跃总距离最远。代码如下

    class Solution {
    public:
        int jump(vector<int>& nums) {
            int step=0,end=0,maxS=0;
            for(int i=0;i<nums.size()-1;++i)
            {
                maxS=max(maxS,i+nums[i]);
                if(i==end)
                {
                    end=maxS;
                    step++;
                }
            }
            return step;
        }
    };


    联系方式:emhhbmdfbGlhbmcxOTkxQDEyNi5jb20=
  • 相关阅读:
    多种方法求解八数码问题
    C#中经常使用的几种读取XML文件的方法
    x86汇编指令具体解释
    数据结构排序系列详解之一 插入排序
    Java实现 蓝桥杯VIP 算法提高 师座操作系统
    Java实现 蓝桥杯VIP 算法提高 师座操作系统
    Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
    Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
    Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
    Java实现 蓝桥杯VIP 算法提高 盾神与砝码称重
  • 原文地址:https://www.cnblogs.com/zl1991/p/14507976.html
Copyright © 2011-2022 走看看