当前位置: 首页 > news >正文

贪心算法学习 跳跃游戏

给你一个非负整数数组 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=-1for i in range(len(nums)-1,0,-1):if nums[i]==0:index_0=ibreak#得到是0的那个索引while index_0>=0:if nums[index_0-1]==nums[index_0]+1:index_0-=1else:return Truereturn 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 = 0while i < len(nums) - 1:if nums[i] == 0:# 从前面找能跨过这个0的人found = Falsefor j in range(i - 1, -1, -1):if nums[j] > i - j:found = Truebreakif not found:return Falsei += 1return 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的位置

所以意思其实是 如果咱俩之间现在可以跳 那我就往前跳 如果不能跳 那我就继续攒着 万一再前面来个大救星呢 就是走着走着发现这个数可以让我跳过来 那我就直接跳过来了 

感觉这样的题 自己想很难想出来 而且有的时候自己写出来了 也是会自我怀疑的 总觉得少了漏了 还是掌握的不好 代码真的和数学是息息相关的 

如果喜欢的话 欢迎点赞!

http://www.lryc.cn/news/612298.html

相关文章:

  • CDP集群中通过Hive外部表迁移HBase数据的操作记录
  • mysql 8递归查询
  • Java基础学习(三):输入输出、控制流程、大数值、数组
  • 客流特征识别准确率提升 29%:陌讯多模态融合算法在零售场景的实战解析
  • 数据结构与算法的认识
  • Android 之 ViewBinding 实现更安全、高效的视图绑定
  • 【渲染流水线】[应用阶段]-[裁剪]以UnityURP为例
  • CGAL Kernel 和 Traits 类深度解析:从官方教程到实践应用
  • prefetch 下载 GEO 数据注意事项
  • Milvus 向量数据库
  • 使用 Helm 在 Kubernetes 中安装 Milvus
  • 安装向量数据库Milvus
  • C++实现线程池(3)缓存线程池
  • Chrontel昆泰-【CH7036A-BF】CH7036 LVDS to HDMI/VGA/LVDS Converter
  • ​ubuntu22.04系统入门 (四)linux入门命令 权限管理、ACL权限、管道与重定向
  • Qt菜单栏与工具栏实战
  • 学习 Android(十四)NDK基础
  • VGG16训练和测试Fashion和CIFAR10
  • 利用C++11和泛型编程改进原型模式
  • 学习 Android(十五)NDK进阶及性能优化
  • 功能安全和网络安全的综合保障流程
  • 分布式事务Seata、LCN的原理深度剖析
  • vue中reactive()和ref()的用法
  • selenium操作指南
  • 状态模式及优化
  • 【机器学习篇】02day.python机器学习篇Scikit-learn基础操作
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘gensim’问题
  • Session 和 JWT(JSON Web Token)
  • python:非常流行和重要的Python机器学习库scikit-learn 介绍
  • 毕业设计选题推荐之基于Spark的在线教育投融数据可视化分析系统 |爬虫|大数据|大屏|预测|深度学习|数据分析|数据挖掘