leetcode 45 跳跃游戏Ⅱ 贪心

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i] 
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

问题的关键在于理解从第一个元素开始找第一个能到达末尾的元素,然后再从第一个元素找能到达上次找的元素 依次找下去直到回到数组开头 思路:每次取局部最优解,从而达到整体最优

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

i            0    1    0    
sum      0    1    2

flag       4    1    0  退出循环

#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#define max(a, b) (((a) > (b)) ? (a) : (b))
int canJump(int* nums, int numsSize){
    if (numsSize==1)
        return 0;
    //数组长度只有一时不需要跳跃
    int count=0;
    int cover,i;//下一步覆盖的最远距离下标
    cover=0,i=0;
    int far=0;// 当前覆盖的最远距离下标
    for (i = 0; i < numsSize - 1; i++) {//遍历从当前位置到当前能够覆盖的最远距离之间的所有位置
        cover = max(nums[i] + i, cover);// 更新下一步覆盖的最远距离下标
        if (i==far){// 遇到当前覆盖的最远距离下标
            far = cover;// 更新当前覆盖的最远距离下标
            count++;
        }
    }
    return count;
}
int main()
{
    int nums[]={2,3,1,1,4};
    int w;
    w=canJump(nums,5);
    printf("%d ",w);

    return 0;
}
#include <stdio.h>
int jump(int* nums, int numsSize){
    int i;
    int sum=0;//记录步数
    int flag=numsSize-1;//初始为能到达数组末端的位置
    while(flag!=0)
    {
        for(i=0;i<numsSize;i++)
        {
            if(nums[i]+i>=flag && flag!=0)//判断是否能到达flag位置
            {
                sum++;//步数加一
                flag=i;//现在找能到达i位置的
                break;
            }
        }
    }
    return sum;
}
int main()
{
    int nums[]={2,3,1,1,4};
    int max;
    max= jump(nums,5);
    printf("%d",max);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include "string.h"
/**
 * 解题思路:动态规划:
 * 1. dp数组:dp[i]表示从0到i的子序列中最大序列和的值
 * 2. 递推公式:dp[i] = max(dp[i-1] + nums[i], nums[i])
        若dp[i-1]<0,对最后结果无益。dp[i]则为nums[i]。
 * 3. dp数组初始化:dp[0]的最大子数组和为nums[0]
 * 4. 推导顺序:从前往后遍历
 */
#define max(a, b) (((a) > (b)) ? (a) : (b))
int canJump(int* nums, int numsSize){
    if (numsSize==1)
        return 0;
    //数组长度只有一时不需要跳跃
    int count=0;
    int cover,i;
    cover=0,i=0;
    while (i<=cover){
        for (i = 0; i < cover + 1; i++) {//遍历从当前位置到当前能够覆盖的最远距离之间的所有位置
            cover = max(nums[i] + i, cover);
            if (cover >= numsSize - 1)
                return count + 1;
        }
        count += 1;
    }
}
int main()
{
    int nums[]={2,3,1,1,4};
    int w;
    w=canJump(nums,5);
    printf("%d ",w);

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值