7-21 leetcode 45

本文探讨了一种固定数组的跳跃游戏问题,分别使用动态规划和贪心算法来寻找最少步数解。动态规划方法通过状态转移方程实现,时间复杂度为O(n²);而贪心算法通过不断更新最远边界,达到O(n)的时间复杂度。两种方法在空间复杂度上分别为O(n)和O(1)。

解法1
读题分析,这是一个固定数组,数组的元素不能随便移动,大概率是扫描遍历数组求解最优值。再进一步分析,可以采取动态规划思想,我们从尾部往前推,对于最后一个元素也就是下标为n-1的元素,它肯定是由前面某个下标为k的元素跳跃了x步,其中k<n-1且x<nums[k],分析到这,状态迁移方程也就很容易列出来了。
状态方程为
dp[i]=dp[k]+1(k<i且k+nums[k]>=i)
dp[0]=0
代码如下:

53
class Solution {
public:
    int jump(vector<int>& nums) {
        int length=nums.size();
        int *dp=new int[length];
        for(int i=0;i<length;i++)
        {
            dp[i]=i;
        }
        for(int i=0;i<length-1;i++)
        {
            for(int j=1;j<=nums[i];j++)
            {
                if(i+j<length)
                {
                    dp[i+j]=dp[i]+1<dp[i+j]?dp[i]+1:dp[i+j];
                }
            }
        }
        return dp[length-1];
    }
};

时间复杂度O(n²)空间复杂度O(n)

解法2
看了官方答案,贪心算法时间复杂度和空间复杂度可以进一步地减少为O(n)和O(1),主要思路就是不断进行贪心计算,计算跳1步最远能走到哪个位置,跳2步最远能走到哪个位置…直到最远位置覆盖最后一个元素。这样所得结果即为步数的下界,也就是最优解。

代码如下:

class Solution {
public:
    int jump(vector<int>& nums) {
        int step=0;//最小步数
        int end=0;//最远边界
        int tmax=0;//临时值,用于计算最远边界
        int length=nums.size();
        for(int i=0;i<length-1;i++)
        {
            tmax=i+nums[i]>tmax?i+nums[i]:tmax;
            if(i==end)
            {
                end=tmax;
                step++;
            }
        }
        return step;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值