当前位置: 首页 > 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.dtcms.com/a/317400.html

相关文章:

  • 利用OJ判题的多语言优雅解耦方法深入体会模板方法模式、策略模式、工厂模式的妙用
  • macOS Python 安装
  • 《设计模式之禅》笔记摘录 - 13.迭代器模式
  • 外观模式(Facade Pattern)及其应用场景
  • 【设计模式精解】从根上理解模板方法设计模式及其应用
  • RN项目环境搭建和使用-Mac版本(模拟器启动不起来的排查)
  • Python虚拟环境完全指南:pyenv vs venv 在macOS上的使用详解
  • Mac安装WebStorm
  • java中Reflection反射(一)
  • MCU AI/ML - 弥合智能和嵌入式系统之间的差距
  • Java猜数字简易小游戏可复制
  • qt6 cmake vscode加载qrc图片资源
  • vue3 el-select el-option 使用
  • 批量打印Excel条形码
  • Linux入门DAY18
  • 单变量单步时序预测:CNN-GRU卷积神经网络结合门控循环单元
  • EasyExcel高效工具类:简化Excel导入导出,支持多Sheet与枚举转换
  • 基于CentOS-7.6部署k8s-1.24.0,containerd作为CRI,nerdctl作为容器管理CLI
  • Datawhale AI 夏令营 让AI读懂财报PDF(多模态RAG)202508
  • bool 类型转换运算符重载
  • WordPress自定义.js文件排序实现方法
  • CSS :is () 与 :where ():简化复杂选择器的 “语法糖”
  • 凸优化:鞍点和对偶停止设计准则
  • 基于PHP的快递管理系统的设计与实现
  • 利用C++11和泛型编程改进原型模式
  • 开发笔记 | 接口与抽象基类说明以及对象池的实现
  • SpringBoot 3.x整合Elasticsearch:从零搭建高性能搜索服务
  • JSON巴巴 - 专业JSON格式化工具:让任何JSON都能完美格式化
  • 基于 Jenkins Pipeline 实现 DITA 文档自动化构建与发布(开源方案)
  • Jenkinsfile各指令详解