LeetCode45——从搜索算法推导到贪心

本文介绍了LeetCode第45题Jump Game II的解题思路,从初始的宽度优先搜索(BFS)方法,讨论了搜索算法的优化,包括状态剪枝和使用优先队列减少计算量。接着,作者通过分析,发现可以进一步优化为贪心算法,通过维护当前步数可移动的最大范围来避免搜索,简化了问题的解决方案。
摘要由CSDN通过智能技术生成

本文始发于个人公众号:TechFlow,原创不易,求个关注


今天是LeetCode系列的第25篇文章,今天我们一起来看的是LeetCode的第45题,Jump Game II。

有同学后台留言问我说,我每次写文章的题目是怎么选的,很简单基本上是按照顺序选择Medium和Hard难度,然后会根据题目内容以及评价过滤掉一些不太靠谱或者是比较变态没有意思的题。

这些题当然会比Easy难度的要难上一点,但是并不是高不可攀的。至少如果你熟悉编程语言,然后会一点基础算法的话,就可以尝试了,我个人觉得不是很高的门槛。

好了,我们回到正题。

今天这题的题目蛮有意思,它是说给定我们一个非负整数的数组。让我们把这个数组想象成一个大富翁里的那种长条形的地图。数组当中的数字表示这个位置向前最多能前进的距离。现在我们从数组0号位置开始移动,请问至少需要移动多少步可以走到数组的结尾?

搜索

我拿到题目的第一反应就是搜索,因为感觉贪心是不可以的。我们把数组当中每个位置的数字称为前进能力,我们当下能达到的最远的位置前进能力可能很差,所以贪心能够达到最远的位置并不可行,举个例子:

[3, 1, 5, 1, 4, 2]

如果我们从0开始的时候走到3的话,由于3的前进能力很小,所以我们需要3步才能走完数组。但是如果我们一开始不走满3,而是走到2的话,我们只需要两步就可以完成。所以贪心是有反例的,我们不能简单地来贪心。而且这题的状态转移十分明显,几乎是裸的顺推。那么我们只需要搜就完事了,由于这是一个求解最优的问题,所以我们应该使用宽度优先搜索。

这个代码我想应该很好写,我们信手拈来:

class Solution:
    def jump(self, nums: List[int]) -> int:
        import queue
        n = len(nums)
        que = queue.Queue()
        que.put((0, 0))
        while not que.empty():
            pos, step = que.get()
            if pos >= n-1:
                return step
            for i in range(pos, min(n, pos+nums[pos] + 1)):
                que.put((i, step+1))

但是显然这么交上去是一定会gg的,想想也知道,我们遍历转移状态的这个for-loop看起来就很恐怖,数组当中的状态很有可能出现重复,那么必然会出现大量的冗余。所以我们需要加上一些剪枝,由于我们使用的是宽度优先搜索,所以所有状态第一次在队列当中弹出的时候就是最优解,不可能同样的位置,我多走几步会达到更优的结果,所以我们可以放心地把之前出现过的位置全部标记起来,阻

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值