贪心算法4

131 阅读2分钟

小知识,大挑战!本文正在参与“   程序员必备小知识   ”创作活动

本文同时参与 「掘力星计划」   ,赢取创作大礼包,挑战创作激励金

3. 跳跃游戏 II

问题:

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

解法1:反向查找出发位置 我们的目标是到达数组的最后一个位置,因此我们可以考虑最后一步跳跃前所在的位置,该位置通过跳跃能够到达最后一个位置。 如果有多个位置通过跳跃都能够到达最后一个位置,那么我们应该如何进行选择呢?直观上来看,我们可以「贪心」地选择距离最后一个位置最远的那个位置,也就是对应下标最小的那个位置。因此,我们可以从左到右遍历数组,选择第一个满足要求的位置。找到最后一步跳跃前所在的位置之后,我们继续贪心地寻找倒数第二步跳跃前所在的位置,以此类推,直到找到数组的开始位置。

class Solution {
public:
//用一个dp记录到当前位置的最小跳跃次数,然后从投开始去更新次数!
    int jump(vector<int>& nums) {
        int n =nums.size();
        int position=n-1;
        int step=0;
        while(position>0)
        {
            for(int i=0;i<n-1;i++)
            {
                if(i+nums[i]>=position)
                {
                    step++;
                    position=i;
                    break;
                }

            }
        }
        return step;

    }
};

最坏情况下O(n2)的复杂度,会超时。 解法1:从前往后,按照步数贪心的去找。 本质和跳跃问题1一样。从哪个当前位置出发,用一个值记录能够跳跃的最远距离,然后在索引小于这个最远距离前,不断遍历,去更新下一步可能的最远距离。 如果下一步的最远距离大于末尾,则停止,返回step+1。

// class Solution {
// public:
// //
//     int jump(vector<int>& nums) {
//         int n =nums.size();
//         int position=n-1;
//         int step=0;
//         while(position>0)
//         {
//             for(int i=0;i<n-1;i++)
//             {
//                 if(i+nums[i]>=position)
//                 {
//                     step++;
//                     position=i;
//                     break;
//                 }

//             }
//         }
//         return step;

//     }
// };



class Solution {
public:
//正向去找当前跳跃次数最大的边界。 一定要先理清楚逻辑
    int jump(vector<int>& nums) {
        int n =nums.size();
        if(n==1) return 0; // 单独考虑出来
        int now_max_pos=nums[0];
        int next_max_pos=nums[0];
        int step=1;
        if(now_max_pos>=n-1) return step;
        for(int i=1;i<n-1;i++)//边界,不需要最后一个元素。  
        {

            if(i<=now_max_pos)
                {
                    next_max_pos = max(next_max_pos,i+nums[i]);//step+1步中的最大边界
                    if(next_max_pos>=n-1) return ++step;
                }
            if(i==now_max_pos)//这个时候才更新
                {now_max_pos = next_max_pos; step++;}

        }

        return step;

    }
};