【Leetcode】55- 跳跃游戏

问题简述

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:
1 <= nums.length <= 10⁴
0 <= nums[i] <= 10⁵

思路分析

解法一:

该问题也是分阶段求解的,每个阶段的最优解是基于之前阶段的最优解(最优子结构),且当前阶段的解与之后阶段的解无关(无后效性),可以考虑采用动态规划求解。

原数组中每个下标对应的值表示的是 在该位置可以跳跃的最大长度 ,初始为nums[i],但我们的问题是:从第一个下标是否可以经过多次跳跃到达最后一个下标。因此对于每一个下标 i i i,不仅要考虑 原始的该位置可以跳跃的最大长度,还需要考虑从该下标之前的其他下标 j ( j < i ) j(j < i) jj<i开始跳跃,跳到当前位置 i i i 后还剩下的可以跳跃的最大长度。如果这个剩余的可以跳跃的最大长度大于当前下标原始的该位置可以跳跃的最大长度,则当前下标的从当前位置往后可以跳跃的最大长度 需要更新,反之不需要更新。

因此我们将每个阶段的状态定义为 从当前位置往后可以跳跃的最大长度,等于原始的该位置可以跳跃的最大长度从上一个位置跳跃至当前位置之后剩下可以跳跃的最大长度 这两者之间的最大值。如果当前状态值大于0,说明可以从当前位置继续往后跳跃。我们从第一个下标开始往后逐个下标进行判断,直到倒数第二个下标,如果其状态值大于0,说明可以到达最后一个下标,则最终的问题结果为true。
我们用状态数组dp来记录每个位置的可以跳跃的最大长度,则状态转移方程为:dp[i] = Math.max(dp[i-1]-1,nums[i])。由于当前状态仅与上一阶段状态有关,使用滚动数组思想对dp数组降维,使用一个变量保存上一阶段状态即可。

具体代码实现见代码示例的 解法一。

解法二:

该问题具有最优子结构和无后效性,也具有贪心选择性质(即原问题的整体最优解可以通过每个子问题的局部最优解来逐步推断得到),因此也可以采用贪心算法求解。
问题:从第一个下标开始,是否可以经过多次跳跃到达最后一个下标。
其子问题为:从第一个下标开始,是否可以跳跃到当前下标之后的下标。可以通过求解经过每个下标时可到达的最远下标,比较是否大于当前下标来判断。每个子问题的解都基于前一个子问题的解。
因此我们遍历数组的每个下标,计算经过每个下标时可到达的最远下标,如果该值有小于等于当前下标的,说明不可到达比当前更远的下标了,对于原问题“是否可以到达最后一个下标”可以直接返回false。否则继续计算,当前下标的可到达的最远下标基于原本可跳跃最远下标和其前一个下标的可到达的最远下标进行比较取更大者进行更新,直到倒数第二个下标,若其可到达的最远下标仍然大于当前下标,说明其后一个下标(即最后一个下标)也是可以到达的,最终返回true。

动态规划算法与贪心算法的异同🌟
相同点:

都具有最优子结构,即原问题可以拆解为对多阶段的子问题求解,每个阶段的问题的最优解包含了子问题的最优解;

不同点:
  • 虽然都具有最优子结构,但子问题结构不同:
    • 动态规划的子问题有重叠,每个当前子问题与之前多个子问题有关(也可能只与上一个问题有关,与具体问题相关)。动态规划问题的求解分阶段进行(每个阶段对应一个子问题),每个阶段是由前几个可能的阶段转移而来的,这几个阶段之间会有重叠(对应了子问题的重叠),我们需要逐步求得所有阶段的状态(对应就是求解出所有子问题的最优解),直到求得最后阶段的状态(对应原问题的最优解)。因此动态规划问题的最优解来自于前几个子问题的最优解;
    • 贪心算法的子问题没有重叠,每个当前子问题只与其上一个子问题有关。当前问题的最优解就是基于前一个子问题的最优解得到的,这样逐个基于上一个子问题求解当前子问题的最优解,直到最后求解原问题,最终可以得到全局最优解。因此贪心算法的最优解来自于其前一个子问题的最优解;
  • 复杂度不同:
    • 动态规划算法的时间复杂度和空间复杂度都会更高,因为需要求解所有子问题并记录最优解;
    • 贪心算法的复杂度会更低;

代码示例

解法一:

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        pre = nums[0]  # 记录前一个下标的 可以继续跳跃的最大长度
        for i in range(len(nums)-1):
            pre = max(pre - 1, nums[i])
            if pre <= 0:
                return False
        return True

解法二:

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        longestind = 0 # 记录从下标0开始每经过一个下标时可跳跃到达的最远下标
        lens = len(nums)
        for i in range(lens-1):
            longestind = max(longestind, i + nums[i])
            if longestind <= i:
                return False
        return True 

测试用例1:
输入:nums = [2,2,0,1,1]
预期输出:true

测试用例2:
输入:nums = [2,0,1,0,1]
预期输出:false

复杂度分析

时间复杂度 O ( n ) O(n) O(n) 需要遍历一遍数组
时间复杂度 O ( 1 ) O(1) O(1) 仅用常数个变量存储

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/597374.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软考中级-软件设计师(九)数据库技术基础 考点最精简

一、基本概念 1.1数据库与数据库系统 数据&#xff1a;是数据库中存储的基本对象&#xff0c;是描述事物的符号记录 数据库&#xff08;DataBase&#xff0c;DB&#xff09;&#xff1a;是长期存储在计算机内、有组织、可共享的大量数据集合 数据库系统&#xff08;DataBas…

python基础---面向对象相关知识

面向对象 可以把数据以及功能打包为一个整体 类: 名称属性(数据)方法 class Person:def __init__(self, name, age):self.age ageself.name namedef print_info:print(self.name, self.age)定义 #经典类 class Dog1:pass# 新式类 class Dog2(object):pass在python3里面这…

LeetCode-741. 摘樱桃【数组 动态规划 矩阵】

LeetCode-741. 摘樱桃【数组 动态规划 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;动态规划&#xff0c;定推初遍举。解题思路二&#xff1a;倒序循环解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个 n x n 的网格 grid &#xff0c;代表一块樱桃地&#xff0…

VMware虚拟机中Linux系统奔溃,怎么办?

一大早启动虚拟机准备开始工作&#xff0c;却遭遇到Linux系统崩溃&#xff0c;屏幕上显示以下错误提示&#xff1a; 这段文本看起来是来自系统引导时的日志信息&#xff0c;提到了一些关于文件系统的问题和建议。根据这段信息&#xff0c;似乎 /dev/sda1 分区中的文件系统存在一…

红日靶场ATTCK 1通关攻略

环境 拓扑图 VM1 web服务器 win7&#xff08;192.168.22.129&#xff0c;10.10.10.140&#xff09; VM2 win2003&#xff08;10.10.10.135&#xff09; VM3 DC win2008&#xff08;10.10.10.138&#xff09; 环境搭建 win7&#xff1a; 设置内网两张网卡&#xff0c;开启…

SeetaFace6人脸检测C++代码实现Demo

SeetaFace6包含人脸识别的基本能力&#xff1a;人脸检测、关键点定位、人脸识别&#xff0c;同时增加了活体检测、质量评估、年龄性别估计&#xff0c;并且顺应实际应用需求&#xff0c;开放口罩检测以及口罩佩戴场景下的人脸识别模型。 官网地址&#xff1a;https://github.co…

dockerk8s常用知识点

1、什么是docker 容器化和虚拟化对比 ▪开源的应用容器引擎&#xff0c;基于 Go 语言开发 ▪容器是完全使用沙箱机制,容器开销极低 ▪Docker就是容器化技术的代名词 ▪Docker也具备一定虚拟化职能 docker三大核心&#xff1a; Docker Engine: 提供了一个可以用来运行和管…

代码+视频,R语言绘制生存分析模型的时间依赖(相关)性roc曲线和时间依赖(相关)性cindex曲线

ROC曲线分析是用于评估一个因素预测能力的手段&#xff0c;是可以用于连续型变量分组的方法。在生存分析中&#xff0c;疾病状态和因素取值均会随时间发生变化。而标准的ROC曲线分析将个体的疾病状态和因素取值视作固定值&#xff0c;未将时间因素考虑在分析之中。在这种情况下…

edge使用心得

1. **性能提升**&#xff1a;基于Chromium的Edge浏览器在速度和响应方面有显著提升&#xff0c;特别是在处理复杂的网页结构和执行JavaScript代码时。这意味着无论是日常浏览还是运行Web应用程序&#xff0c;都能享受流畅的用户体验。 2. **更好的兼容性**&#xff1a;由于与G…

大模型最新消息

最新消息如下&#xff1a; 大语言模型服务的多样化&#xff1a;互联网上出现了许多免费的大语言模型服务&#xff0c;如OpenAI的ChatGPT、Google的Gemini、Anthropic的Claude、Meta的Llama等。这些服务的推出使得大语言模型的应用更加广泛和便捷。软银和苹果的AI新动向&#x…

​​【收录 Hello 算法】3.3 数字编码

目录 3.3 数字编码 3.3.1 原码、反码和补码 3.3.2 浮点数编码 3.3 数字编码 Tip 在本书中&#xff0c;标题带有 * 符号的是选读章节。如果你时间有限或感到理解困难&#xff0c;可以先跳过&#xff0c;等学完必读章节后再单独攻克。 3.3.1 原码、反码和补码 在…

迅睿CMS中实现关键词搜索高亮

在迅睿CMS系统中实现关键词搜索高亮是提升用户体验和搜索效果的重要手段。当用户搜索某个关键词时&#xff0c;将搜索结果中的关键词高亮显示&#xff0c;可以帮助用户更快速地定位到所需信息。 关键词高亮的实现 在迅睿CMS中&#xff0c;你可以使用内置的dr_keyword_highlig…

Study--Oracle-01-单实例部署Oracle11G-R2

Oracle版本发布介绍 Oracle 19c和12c和11g功能区别_数据库_oracle_支持 一、CentOS 7 环境准备 1、软件准备 操作系统&#xff1a;CentOS 7 数据库版本: Oracle11g R2 2、操作系统环境配置 关闭selinux &#xff0c;编辑 /etc/selinux/config文件&#xff0c;设置SELINU…

C语言例题34、反向输出字符串(递归方式)

题目要求&#xff1a;输入5个字符后&#xff0c;使用递归方式逆序输出 #include <stdio.h>void reverse(int num) {char cur_char;if (num 1) {cur_char getchar();printf("逆序输出为&#xff1a;");putchar(cur_char);} else {cur_char getchar();revers…

宏电全栈式IoT赋能供排水智能监测,护航城市生命线

城市供水、排水系统是维系城市正常运行、满足群众生产生活需要的重要基础设施&#xff0c;是城市的“生命线”。随着城市化进程加快&#xff0c;城市规模不断扩大&#xff0c;地下管线增长迅速&#xff0c;城市“生命线安全”的监管日益面临挑战。 宏电作为物联网行业的领航者…

软件测试与管理:黑盒测试-等价类划分法和 边界值分析法

知识思维导图&#xff1a; 例题1&#xff1a;日期检查功能的等价类划分 设有一个档案管理系统&#xff0c;要求用户输入以年月表示的日期。假设日期限定在1990年1月~2049年12月&#xff0c;并规定日期由6位数字字符组成&#xff0c;前4位表示年&#xff0c;后2位表示月。现用等…

后台启动HIVE的JDBC连接

后台启动HIVE的JDBC连接 生活就像一杯咖啡&#xff0c;有时苦涩&#xff0c;有时香甜&#xff0c;但都是值得品味的经历。无论遇到什么挑战&#xff0c;记住在每一天的开始&#xff0c;你都有机会给自己倒上一杯清新的力量&#xff0c;为心灵添一抹温暖。勇敢地面对生活的苦与甜…

10000 字详细讲解 Spring 中常用注解及其使用

如下图京东购物页面&#xff0c;当我们选择点击访问某一类商品时&#xff0c;就会向后端发起 HTTP 请求&#xff0c;当后端收到请求时&#xff0c;就会找到对应的代码逻辑对请求进行处理&#xff0c;那么&#xff0c;后端是如何来查找处理请求相对应的代码呢&#xff1f;答案就…

C++使用单链表实现一元多项式的加,乘操作

相邀再次喝酒 待 葡萄成熟透 但是命运入面 每个邂逅 一起走到了 某个路口 是敌与是友 各自也没有自由 位置变了 各有队友 首先&#xff0c;按照惯例&#xff0c;十分欢迎大家边听歌边观看本博客&#xff01;&#xff01; 最佳损友 - 陈奕迅 - 单曲 - 网易云音乐 (163.com) 一…

leetcode295. 数据流的中位数

class MedianFinder {//A为小根堆&#xff0c;B为大根堆List<Integer> A,B;public MedianFinder() {A new ArrayList<Integer>();B new ArrayList<Integer>();}public void addNum(int num) {int m A.size(),n B.size();if(m n){insert(B,num);int top …
最新文章