您的位置:首页 > 其它

每日一题 Day4--leetcode45--跳跃游戏 II

2020-06-04 06:45 218 查看

每日一题 Day4–leetcode45–跳跃游戏 II

题目

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

链接为leetcode中文社区,题目没有区别,感觉很好用

题面描述: 给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

示例:

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

说明:假设你总是可以到达数组的最后一个位置。

解析+c语言实现

题目为典型的贪心算法,即由每一步的最优解推出全局最优解,关于贪心思想可参考上一篇博客:Day3–leetcode53–最大子序和

从后往前贪心

题目要求求出跳到最后一个点所需要的最少步数,那么想要跳到最后一个点,一定需要跳到 进行最后一步跳之前的那个点,所以只需要找到这个点的最小可能再去套娃找到 进行倒数第二不跳之前的那个点,以此类推。

在代码实现时我们只需要从左到右寻找哪一个位置x可以跳到最后一个点last,然后再从头寻找哪一个位置可以跳到刚刚的位置x,便可以循环解决,直到找到第一个点即第一步。

int jump(int* nums, int numsSize){
int step=0;
int i=0,now=numsSize-1;
for(i=0;i<now;i++)//从左到右寻找哪个店可以跳到now现在需要到达的点
{
if(i+nums[i]>=now)//如果找到了这个点
{
now=i;//下次循环便是找哪个点可以跳到这个点
i=-1;//下次循环需要从头开始寻找
step++;
}
}
return step;
}

执行结果:

可以分析得到,从后往前贪心需要n的复杂度,而每一步中找到哪个点也是n的复杂度,所以此方法时间复杂度为O(n2),耗时656ms。

从前往后贪心

从前往后的贪心即从第一步开始求出可以到达的最远距离,然后再求出从最远距离以内的点所可以到达的最远距离,直到到达最后一个点,保证每一步为最优解,推出全局最优解

举一个栗子:

[2,3,1,1,4]

第一步从位置0数字2开始,可以达到得到最远距离为2,然后考虑位置1和位置2可以到达的最远距离(因为可以最远跳到2那么位置1一定可以到达),第二步最远距离为**4(1+3)**即为对后一个点,所以最少需要2步。

int jump(int* nums, int numsSize){
int left=0,right=0;//left 和 right 存储这一步可以跳到的最小和最大距离
int step=0;//步数
int i;
int max=0;//记录每一步可以跳到的最远距离
while(right<numsSize-1)
{
for(i=left;i<=right;i++)//当从left到right遍历后找到最远距离max
{
max=max>(nums[i]+i)?max:(nums[i]+i);
}
left=right+1;//下一步最近即从上一步的点+1起跳
right=max;//下一步最远即从max起跳
step++;
}
return step;
}

执行结果:

可以分析到,此方法只从左到右遍历过一遍所以时间复杂度为O(n),耗时8ms

关于每日一题

疫情在家学业不重,又觉得自己算法很薄弱,所以希望可以每天刷一道算法题。
在翻leetcode找题的时候看到了推出的每日1题打卡计划,觉得不错,在此写下来加深记忆,也希望可以帮到其他人 。

今天只写了c语言实现,最近在学习python和go,在复习java,过几天尝试不同语言实现。

Day4总结:

leetcode45是一道很典型的贪心算法,可以作为学习贪心的入门题目,读懂算法以后会觉得很巧妙,amazing!

如果不出意外,每天这个时间更,欢迎监督,大家共勉。

欢迎关注公众号,日常同步博客内容,每日零点更新

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: