zoukankan      html  css  js  c++  java
  • 【LeetCode】45.跳跃游戏2

    题目链接

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

    题目描述

    给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。

    示例:
    输入: [2,3,1,1,4]
    输出: 2
    解释: 跳到最后一个位置的最小跳跃数是 2。
         从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
    
    说明:
    假设你总是可以到达数组的最后一个位置。

    解题思路

    本题考查的是贪心思想。一开始我采取的贪心策略是:每次在跳跃的时候,都选择可跳跃范围内数组的最大值。

    例如[2,3,1,1,2,4,1,3],数组起始位置对应的值为2,代表着下一次可跳跃范围为(3,1),对应的数组下标为(1,2),在可跳跃范围内选择对应数组的最大值也就是选择(3,1)中的最大值3。

    采用这种策略能过一半的用例,但是当用例为[10,9,8,7,6,5,4,3,2,1,1,0]时,该贪心策略失败。

    正确的贪心策略是:每次在跳跃的时候,都选择可跳跃范围内下一次可跳跃最远距离的点。

     绿色框为当前位置,粉色框为可跳跃范围。

    AC代码

     1 class Solution {
     2 public:
     3     int jump(vector<int>& nums) {
     4         int ans = 0;
     5         int temp = 0;
     6         if(nums.size() == 1) return 0; //6-7行代码是两个特例,我是先完成8-29行代码之后,才添加的两个特例,否则不能AC。
     7         if(nums[0] >= nums.size() - 1) return 1; 
     8         for(int i = 0; i < nums.size(); )
     9         {
    10             int len = INT_MIN;
    11             for(int j = i; j < nums.size() && j <= i + nums[i]; j++) //11-18行代码就是进行下一次可达最远距离进行的求解。
    12             {
    13                 if(nums[j]+j > len)
    14                 {
    15                     len = nums[j]+j;
    16                     temp = j;
    17                 }
    18             }
    19             i = temp;
    20             ans++;
    21             if(len >= nums.size() - 1)
    22             {
    23                 ans++;
    24                 break;
    25             }
    26         }
    27         return ans;
    28     }
    29 };

    虽然说利用了双重for循环,但是其时间复杂度为O(n),空间复杂度为O(1)。

    代码经过优化后,利用一个for循环即可。

    在遍历数组时,我们不访问最后一个元素,这是因为在访问最后一个元素之前,我们的边界一定大于等于最后一个位置,否则就无法跳到最后一个位置了。如果访问最后一个元素,在边界正好为最后一个位置的情况下,我们会增加一次「不必要的跳跃次数」,因此我们不必访问最后一个元素。

     1 class Solution {
     2 public:
     3     int jump(vector<int>& nums) {
     4         int step = 0;
     5         int end = 0;
     6         int maxlen = INT_MIN;
     7         for(int i = 0; i < nums.size() - 1; i++)
     8         {
     9             maxlen = max(maxlen,nums[i]+i);
    10             if(i == end)
    11             {
    12                 step++;
    13                 end = maxlen;
    14             }
    15         }
    16         return step;
    17     }
    18 };
  • 相关阅读:
    在luogu上嫖到了一张感觉很NB的图
    luoguP6028算术 题解(推柿子+整除分块+调和级数)
    notebook
    不氵的 0xd
    点分治&&DSU on tree学习笔记
    洛谷10月月赛2T1题解
    概率与期望题库题目整理
    TiDB-TiUP工具使用
    TiDB-单机学习环境部署(4.X版本)
    DB-异构数据库迁移工具
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/12828436.html
Copyright © 2011-2022 走看看