leetcode 45. Jump Game II (dp)

题目

在这里插入图片描述
在这里插入图片描述

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

解题过程

解法1

首先,这道题我想到了用map来解决,其实整型数组也可以,但还要考虑长度的问题有点麻烦就算了(其实就是懒)

class Solution {
public:
    int jump(vector<int>& nums) {
        int l = nums.size();
		if(l==1) return 0;
		int cnt=0,pos=0;//cnt为跳跃次数,pos为当前位置 
		unordered_map<int,int> pre,flag;
		//pre[cnt]为上一跳后选择的下一个最优结点,
		//flag为pre[cnt]结点所能到达的最远距离
		//(也是截至到当前结点的最远距离) 
		//pre与flag一一对应 
		pre[0]=0,flag[0]=pre[0]+nums[0];
		if(flag[0]>=l-1) return cnt+1;
		pos++,cnt++;
		while(pos<l){
			if(pos>flag[cnt-1]) cnt++;
			int dis=pos+nums[pos];
			if(dis>=nums.size()-1) break;
			if(dis>flag[cnt]){
				pre[cnt]=pos;
				flag[cnt]=dis;
			} 
			pos++;
		}
		return cnt+1;
    }
};

这个解法看着很乱,我大致解释一下,就是pre每一层存储的都是上一条的最优结点,flag是其对应的最远距离。如果超出了上一条的最大辐射范围,就开启一次新的跳跃。

但是,这个思路完全不需要map或者数组,其实只需要维护几个整型变量即可,所以就有了解法2

解法2

class Solution {
public:
    int jump(vector<int>& nums) {
        int l = nums.size();
		if(l==1) return 0;
		int cnt=0,pos=0;//cnt为跳跃次数,pos为当前位置 
		int pre,flag,t1=0,t2=0;
		//pre为上一跳的最优结点,flag为pre结点所能到达的最远距离 
		//t1为当前跳跃的最优结点,t2为t1结点所能到达的最远距离
		pre=0,flag=pre+nums[0]; 
		if(flag>=l-1) return cnt+1;
		pos++,cnt++;
		while(pos<l){
			if(pos>flag) { //超出上一跳最远范围,更新参数
				cnt++;
				pre=t1;
				flag=t2;
				t1=0;
				t2=0;
			}
			int dis=pos+nums[pos];
			if(dis>=nums.size()-1) break;
			if(dis>t2){ // 选取这一跳的最优结点
				t1=pos;
				t2=dis;
			} 
			pos++;
		}
		return cnt+1;
    }
};

具体的解释我都放在注释里了,但还是好长啊,根本没有大佬那种几行代码解决问题的快感,于是我去题解里学习了一下,果然发现了大佬,其实思路和Jump Game很像。

解法3

作者:ikaruga
链接:https://leetcode.cn/problems/jump-game-ii/solution/45-by-ikaruga/
来源:力扣(LeetCode)
class Solution {
public:
    int jump(vector<int>& nums) {
        int cnt=0,last=0,flag=0;
        for(int i=0;i<nums.size()-1;i++){
            flag=max(flag,i+nums[i]);
            if(i==last){
                last=flag;
                cnt++;
                if(flag>=nums.size()-1) break;//我多加了一行代码,提前退出节省时间
            }
        }
        return cnt;
    }
};

其实大佬的核心逻辑很像层次遍历,关键代码就是if (i == end),这其实就是层次遍历中对层尾的判断,牛!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值