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

从零开始的CPP(37)跳跃游戏,动态规划,贪心算法

leetcode45

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i] 
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

我最开始用递归解决

int jump(vector<int>& nums) {set<int> times;int time = 0;help(nums, 0, times, time);if (times.empty()) return 0;return *times.begin();
}
void help(vector<int>& nums, int i, set<int>& times, int& time) {if (i >= nums.size()-1) {times.insert(time);return;}else if (nums[i] == 0) {return;}for (int k = 1; k <= nums[i]; k++) {time++;help(nums, i + k, times, time);time--;}
}

时间复杂度高,无法通过。

于是使用动态规划。动态规划核心是储存。我们这里需要储存两个数值:1.当前已经达到的最远距离2.下一步能达到的最远距离

#include <vector>
using namespace std;class Solution {
public:int jump(vector<int>& nums) {int n = nums.size();if (n <= 1) return 0; // 如果只有一个元素或为空,则不需要跳跃int maxPos = 0;       // 当前能达到的最大位置int end = 0;          // 当前步数能达到的最远位置int step = 0;         // 跳跃的步数for (int i = 0; i < n - 1; i++) { // 不需要检查最后一个位置if (maxPos >= i) {maxPos = max(maxPos, i + nums[i]); // 更新最远能跳到的位置if (i == end) {end = maxPos; // 更新当前步数能达到的最远位置step++;       // 增加一步if (end >= n - 1) break; // 如果已经达到或超过终点,则退出循环}}}return step;}
};
if (i == end) {end = maxPos; // 更新当前步数能达到的最远位置step++;    

 这里其实是i在追赶end(上一层是追赶maxPos),只有追赶上了,才能谈更新。

 

解决方案分析

为了找到最少的跳跃次数,我们需要考虑如何有效地覆盖尽可能多的索引。我们可以通过动态规划的方式来解决这个问题。这里的关键在于理解每次跳跃能够覆盖的范围,并且如何更新这个范围以达到最优解。

代码解释

  1. 初始化

    • int n = nums.size();:获取数组的大小。
    • if (n <= 1) return 0;:如果数组只有一个元素或为空,则不需要跳跃,直接返回0。
  2. 定义变量

    • int maxPos = 0;:当前能达到的最大位置。
    • int end = 0;:当前步数能达到的最远位置。
    • int step = 0;:跳跃的步数。
  3. 遍历数组

    • 我们使用一个循环遍历数组中的每一个元素,除了最后一个元素(因为我们不需要检查最后一个元素是否能够被到达,而是要计算到达它的最少步骤)。
  4. 更新最大位置

    • 对于每个索引 i,我们更新 maxPos 为 i + nums[i] 和 maxPos 中的较大值。这是因为从当前位置 i 出发,我们最多可以跳到 i + nums[i] 的位置。
      maxPos = max(maxPos, i + nums[i]);
  5. 更新步数

    • 当 i 达到了 end(即当前步数所能达到的最远位置),我们就增加了一步,并将 end 更新为新的 maxPos
      if (i == end) {end = maxPos;step++;
      }
    • 如果 end 已经达到或超过了终点 n - 1,则跳出循环,因为这意味着我们已经找到了最少的跳跃次数。
  6. 返回结果

    • 最后返回 step,即所需的最少跳跃次数。

贪心算法思想

贪心算法的基本思想是在每一步选择局部最优解,以期达到全局最优解。在这个问题中,我们的目标是最小化跳跃次数。为此,我们可以尝试以下策略:

  • 在每一步,我们都会尝试覆盖尽可能多的索引,以减少总的跳跃次数。
  • 我们将维护两个关键变量:end 和 maxPos
    • end 表示当前步数下能到达的最远位置。
    • maxPos 表示从当前步数开始到下一步之间能到达的最远位置。
  • 我们会不断地更新 maxPos,并在达到 end 时更新 end 为 maxPos,同时增加跳跃次数。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 纷享销客CRM AI产品架构概览、产品特色
  • Github 2024-08-09 开源项目日报 Top10
  • git的一些操作指令
  • 工作随记:oracle中偶发遇到存储过程编辑,删除等卡死问题
  • 下一代 AI 搜索引擎 MindSearch:多智能体 + 系统2,模拟人类认知过程的 AI 搜索引擎
  • 在Ubuntu 18.04上安装和配置pgAdmin 4服务器模式的方法
  • Docker最佳实践(六):安装Nacos
  • 9.动态导航栏怎么做
  • uniapp微信小程序 canvas绘制圆形半透明阴影 createCircularGradient函数不支持透明度部分解决方案
  • 100道C/C++面试题
  • mysql8.4.2数据库做主从复制
  • 【Python基础】Python六种标准数据类型中哪些是可变数据,哪些是不可变数据
  • SQL Zoo 9-.Window functions
  • linux证书生成详解
  • 堆的实现(偷懒版)
  • CSS居中完全指南——构建CSS居中决策树
  • C学习-枚举(九)
  • C语言笔记(第一章:C语言编程)
  • leetcode388. Longest Absolute File Path
  • LintCode 31. partitionArray 数组划分
  • web标准化(下)
  • 编写符合Python风格的对象
  • 给第三方使用接口的 URL 签名实现
  • 诡异!React stopPropagation失灵
  • 机器学习 vs. 深度学习
  • 前端临床手札——文件上传
  • 微信小程序开发问题汇总
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 通过调用文摘列表API获取文摘
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • #1015 : KMP算法
  • #QT项目实战(天气预报)
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (3) cmake编译多个cpp文件
  • (c语言)strcpy函数用法
  • (八十八)VFL语言初步 - 实现布局
  • (编译到47%失败)to be deleted
  • (附源码)计算机毕业设计高校学生选课系统
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (六)Flink 窗口计算
  • (六)软件测试分工
  • (十) 初识 Docker file
  • (一) storm的集群安装与配置
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET CORE 第一节 创建基本的 asp.net core
  • .NET/C# 的字符串暂存池
  • .net的socket示例
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!
  • /etc/shadow字段详解
  • @Bean注解详解
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @ResponseBody