算法设计与分析第六次作业

leetcode 45 Jump Game II

题目描述如下

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
Example:
Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2.
Jump 1 step from index 0 to 1, then 3 steps to the last index.
Note:
You can assume that you can always reach the last index.

首先这道题我们可以先看下leetcode 55:Jump Game
题目描述如下:

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
Example 1:
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:
Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum
jump length is 0, which makes it impossible to reach the last index.

这道题看上去很复杂,因为从一个点出去有很多种可能性,看起来可能要用到广搜深搜之类的搜索算法,但是其实仔细一想这就是一个贪心问题,对于任意的[a0…ak]这个序列我们都可以找到一个最远可以到达的点,而如果这个点是ak的话自然就不能继续往下走了,所以这题的思路就是按顺序遍历数组中的每一个元素,计算目前的最远点,然后判断中间有没有走不下去的时候即可,代码如下:

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

再回到这道题的变种,这道题和上题很像,但是把判断是否能到达最后一个点换成了最短路径,我一开始觉得和上面一样的做就可以了,只需在每一次cur改变的时候增加步数就好了,但是后面交上去看到错误的样例才发现其实这样找的并不是最短的路径,比如[7,0,9,6,9,6,1,7,9,0,1,2,9,0,3]这个样例,虽然第三个点的9能比第一个点的7走的更远,但实际上7直接走到nums[7],然后nums[7]直接就可以到终点,这样实际上是没有必要走到9的,所以正确的修改思路应该是再维护一个变量保存“某个阶段”找到的最远点,而在这个阶段中找到的其他点其实可以忽略,这样让更新最远点的次数尽量少,同样也对应步数尽量少,代码如下:

class Solution {
public:
    int jump(vector<int>& nums) {
        int cur = 0,ans = 0,maxPos = 0;
        for(int i = 0; i < nums.size(); i++){
            if(maxPos >= nums.size() - 1){
                break;
            }
            if( i + nums[i] > cur){
                cur = i + nums[i];
            }
            if(i == maxPos){
                maxPos = cur;
                ans++;
            }           
            
        }
        return ans;
    }
};

代码时间复杂度很明显是O(n)

总之这两道题主要就是要意识到这是一个贪心算法的题,虽然在leetcode里面是hard的题但是其实思路并不是太难想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值