45. Jump Game II

本文介绍了解决跳跃游戏问题的两种算法实现方法。方法一使用线段树进行动态规划,能够高效地查找并更新可达范围内的最小跳跃次数。方法二采用贪心算法,通过维护当前步骤的最大可达距离来简化问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一:

线段树,从后往前dp,当前dp值为从当前点能跳到的后面最长的距离内的最小dp值+1,线段树可以O(log(n))的时间内从后面找到最小的dp值

struct segTree{
    int l,r;
    int v;
    segTree* left,*right;
    segTree(int val):v(val),left(NULL),right(NULL){}
};
void build(segTree*& root,int l,int r)
{
    if(l==r)
    {
        root=new segTree(l);
        root->l=l;
        root->r=l;
        return;
    }
    root=new segTree(l);
    root->l=l;
    root->r=r;
    int mid=(l+r)>>1;
    build(root->left,l,mid);
    build(root->right,mid+1,r);
}
void insert(segTree*& root,int dp[],int ind,int val)
{
    if(root->l==root->r&&root->l==ind)
    {
        return;
    }
    if(dp[root->v]>val)
        root->v=ind;
    int mid=(root->l+root->r)>>1;
    if(ind<=mid)
        insert(root->left,dp,ind,val);
    else
        insert(root->right,dp,ind,val);
    
}
int search(segTree* &root,int dp[],int l,int r)
{
    if(root->l>r||root->r<l)
        return -1;
    if(root->l==l&&root->r==r)
        return root->v;
        
    int mid=(root->l+root->r)>>1;
    if(r<=mid)
        return search(root->left,dp,l,r);
    else if(l>=mid+1)
        return search(root->right,dp,l,r);
    int lind=search(root->left,dp,l,mid);
    int rind=search(root->right,dp,mid+1,r);
    if(dp[lind]>dp[rind])
        return rind;
    return lind;
}
class Solution {
public:
    int jump(vector<int>& nums) {
        int n=nums.size();
        if(n<=1)
            return 0;
        int dp[n];
        for(int i=0;i<n;i++)
            dp[i]=n;
        dp[n-1]=0;
        segTree* root;
        build(root,0,n-1);
        insert(root,dp,n-1,0);
        
        for(int i=n-2;i>=0;i--)
        {
            if(nums[i]==0)
                continue;
            int ind=search(root,dp,i+1,min(i+nums[i],n-1));
            dp[i]=dp[ind]+1;
            insert(root,dp,i,dp[i]);
        }
        return dp[0];
    }
};


方法二:贪心,维持一个当前步能到达的最大值,多加一步能到达的最大值

class Solution {
public:
    int jump(vector<int>& nums) {
        int n=nums.size();
        if(n<=1)
            return 0;
        
        int curRch=0;
        int curMax=0;
        int ret=0;
        for(int i=0;i<n;i++)
        {
            if(curRch<i)
            {
                ret++;
                curRch=curMax;
            }
            curMax=max(curMax,nums[i]+i);
        }
        return ret;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值