贪心算法学习 跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false

我思考的是 是不是只要不跳到位置0 那么就不会导致没办法到最后一步?我先假设在这个数组中只有一个0 那么如果这个0前面的序列是按照差值为1进行递增的 那么就不行

复制代码
class Solution(object):
    def canJump(self, nums):
        min=float('inf')
        for i in range(len(nums)):
            if nums[i]<min:
                min=nums[i]
        if min!=0:
            return True#只要没有0 那么一定是可以到达的
        #如果有0的话 只要可以不经过这个0 那么就可以达到最后
        #那么跳不过的是有啥情况呢?只要0前面不是递增的就行
        #现在假设在这个数组中只会有一个0 我们来写代码
        index_0=-1
        for i in range(len(nums)-1,0,-1):
            if nums[i]==0:
                index_0=i
                break#得到是0的那个索引
        while index_0>=0:
            if nums[index_0-1]==nums[index_0]+1:
                index_0-=1
            else:
                return True
        return False
solution=Solution()
result=solution.canJump([3,2,1,0,4])
print(result)

但是实际情况是 这个数组中可能有多个0 对于第一个0来说 它之前的元素不能是连续的等差数列 然后过了这个0之后继续往下走 不管是跳到哪一步 0前面的都不能是等差数列 只要两个0之间的 这些元素 不和第二个0构成一个等差数列 那就没事 一旦有等差数列肯定就必须要经过0了 好的我们来补全代码

然后我突然发现还是不对啊 因为比如 2 3 4 3 2 1 0 这样的 即使0前面的并不是等差数列 那不还是一定会经过0吗?所以我找的规律不对 救命我不会找了 这个到底是啥规律啊 我继续找 3 2 1 0到不了是不是最大的3 最远只能到0 如果是 7 3 2 1是不是就没问题

再看 是不是只要0前面存在的这个元素 它的大小能超过和0的距离是不是就可以 我们来看一些情况是不是这样的:2 3 4 6 0 4 5 2 3 0 3 2 2 2 0 7 5 5 4 4 2 2 1 0 第一个0 6超过了 第二个 3可以 第三个 2也可以 最后一个虽然是到0但是0是最后一个 也没关系

那我们就有想法了

  • 一旦发现 0(意味着当前点不能再往前跳),

  • 就从它前面的数字里找有没有人"跳得够远",能跨过这个 0

  • 如果找不到这样的"救兵",就卡住了。

发现是0 看前面有没有满足的 你可以一直往前面找 直到找到一个满足的没事 如果有 那没事 肯定是有救兵的 直接Break 并且i+=1 如果没有 就直接return false就行

来写代码:

复制代码
class Solution(object):
    def canJump(self, nums):
        i = 0
        while i < len(nums) - 1:
            if nums[i] == 0:
                # 从前面找能跨过这个0的人
                found = False
                for j in range(i - 1, -1, -1):
                    if nums[j] > i - j:
                        found = True
                        break
                if not found:
                    return False
            i += 1
        return True
solution=Solution()
result=solution.canJump([3,2,1,0,4]) 
print(result)

不要觉得晕啊 也不要考虑那么多 只要能往下走就证明没问题 (这个是我对我自己说的 虽然这个方法是通过测试的 但是我总是会担心中间什么数字会出什么岔子 这个是我的想法 )

然后我看有更好的方法,我们一起来学习一下

"目标更新法"(也叫贪心跳跃法),逻辑非常简洁,而且效率高。我们把目标点不断向前移动,只要当前位置能跳到目标,就把目标更新成当前位置,最后看目标是不是移动到了起点就行

class Solution(object):

def canJump(self, nums):

goal = len(nums) - 1 # 终点位置

for i in range(len(nums) - 2, -1, -1): # 从倒数第二个元素往前遍历

if nums[i] >= goal - i:

goal = i # 如果当前位置能跳到目标,更新目标为当前位置

return goal == 0 # 如果目标回到起点,说明可以跳到终点

3,2,1,0,4\] 从0开始 这个数值并不大于等于4-3 所以并不能从当前位置跳到目标 意思就是0这个是数字0 根本没办法到下一步 所以不行 意思就是我就看咱俩之间的距离长度 你这个数值够不够 如果你够了 证明你是可以来到我这个地方的 那么我不妨直接将终点移动到你那个位置 反正你是可以来的 就是去更新goal 看能不能更新到0 比如\[2, 3, 1, 1, 4\] 从1开始 二者之间可以 跳到1 也可以到1 3可以到1 继续移动 2可以到3 继续移动 那么疑问?那这样的话会因为遇到0就直接导致不行了吗?其实是不会的 举个例子 7 8 0 2 4 2大于等于 1 所以goal=3 0并不大于等于 1 继续往前 8\>=3-2 所以现在跳到8的位置 所以意思其实是 如果咱俩之间现在可以跳 那我就往前跳 如果不能跳 那我就继续攒着 万一再前面来个大救星呢 就是走着走着发现这个数可以让我跳过来 那我就直接跳过来了 感觉这样的题 自己想很难想出来 而且有的时候自己写出来了 也是会自我怀疑的 总觉得少了漏了 还是掌握的不好 代码真的和数学是息息相关的 如果喜欢的话 欢迎点赞!

相关推荐
墨迹的陌离7 分钟前
【Linux】重生之从零开始学习运维之主从MGR高可用
学习
小一亿19 分钟前
【0基础PS】PS工具详解--直接选择工具
学习·平面·adobe·信息可视化·传媒·photoshop
日 近 长 安 远1 小时前
[学习笔记-AI基础篇]04_chatGPT原理和发展
笔记·学习·chatgpt
慕y2743 小时前
Java学习第一百零九部分——Jenkins(一)
java·学习·jenkins
Luca-s-4 小时前
KafKa 项目 -- GitHub 学习
学习
一叶怎知秋5 小时前
【openlayers框架学习】九:openlayers中的交互类(select和draw)
前端·javascript·笔记·学习·交互
艾莉丝努力练剑5 小时前
【C/C++】形参、实参相关内容整理
c语言·开发语言·c++·学习
@国境以南,太阳以西6 小时前
快速准确的千兆像素病理图像分类,采用分层蒸馏多实例学习(每日一文)
学习
Fuliy966 小时前
【数字图像处理系列笔记】Ch03:图像的变换
图像处理·人工智能·笔记·学习·计算机视觉·数字图像处理