LeetCode hard 45. Jump Game II

这道题虽然在难度上是hard,但是想要做出来还是挺容易的,可能是我投机取巧了?它的tag写的是greedy,但是我用的是动态规划,不知道算不算是违规了。

----------------------题目---------------------------

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.

For example:
Given array A = [2,3,1,1,4]

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.

-------------------题解-----------------------

题目意思很清楚,给一个数组,数组代表了在这个点下能够跳跃的最大步数(假设一个index就是一步),也就是说从当前点 i 开始我可以跳一次就到达从 i+1 到  i+A【i】整个区间所有的点。从第一个点开始,要想到达最后一个点,求所需要的最小的跳跃数。好吧,我的第一想法就是用动态规划做,建一个数组记录一下从第一个点到当前点的最小跳跃数,然后从前向后遍历题目的给定数组即可,如果你完成到这里你已经成功了一半了,提交后你会发现你超时了,所以说我猜这道题之所以是hard的原因就在这里了,但是一旦你观察一下你超时的那个点的数据,你会发现你那是一个递减数列,这样一来你的算法就做了大量的无用功,举个栗子,假设数组第一个数的大小是2,第二个数是1,我的目标是到达第三个点,我们可以发现,从第一个点就完全可以到达第三个点,无需去计算第二个点,但是这个栗子可能是有点特殊,好吧,我们来推广一下,第 i 个点数为A【i】,第 i+1 个点数为A【i+1】,但是A【i+1】小于A【i】,问题就在于从第 i 个点我可以到达所有第 i+1 开始到达的所有点,那么请问我有必要还去计算i+1么,其实你稍微模拟一下就可以发现你从起点到达第i个点的最小跃数肯定是会小于等于到达第i+1个点的最小跃数的。那么我们的代码就可以很清楚的写出来了。

#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    static int jump(vector<int>& nums) {
        int l=nums.size();
        int mj[l];
        for(int i=0;i<l;i++)
        mj[i]=100000;
        mj[0]=0;//初始化
        for(int i=0;i<l;i++)
        {
        	int maxj=nums[i];
        	if(i-1>0&&nums[i]<nums[i-1])//优化,即当 nums[i]<nums[i-1]时就跳过第i个点的计算,如上文所说
        	continue;
        	for(int j=1;j<=maxj&&j+i<l;j++)
        	{
        		mj[j+i]=min(mj[j+i],mj[i]+1);//状态转移方程
        	
			}
		}
		return mj[l-1];
    }
};
整个思考过程是比较简单的,但是这分代码的时间花费比较多的,只超过了25%的提交代码,说明还有很大的优化空间的,但是我尝试了半个小时,没什么进展就放弃了。好了,今天的题解也到此告一段落了。

---------------------手动分割线--------------------

see you next illusion



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值