【动态规划】C++算法:403.青蛙过河

作者推荐

【动态规划】C++算法312 戳气球

LeetCode:403 青蛙过河

一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。
给你石子的位置列表 stones(用单元格序号 升序 表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一块石子上)。开始时, 青蛙默认已站在第一块石子上,并可以假定它第一步只能跳跃 1 个单位(即只能从单元格 1 跳至单元格 2 )。
如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1 个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。
示例 1:
输入:stones = [0,1,3,5,6,8,12,17]
输出:true
解释:青蛙可以成功过河,按照如下方案跳跃:跳 1 个单位到第 2 块石子, 然后跳 2 个单位到第 3 块石子, 接着 跳 2 个单位到第 4 块石子, 然后跳 3 个单位到第 6 块石子, 跳 4 个单位到第 7 块石子, 最后,跳 5 个单位到第 8 个石子(即最后一块石子)。
示例 2:
输入:stones = [0,1,2,3,4,8,9,11]
输出:false
解释:这是因为第 5 和第 6 个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。
参数范围
2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0
stones 按严格升序排列

动态规划

理论时间复杂度😮(nn)。
dp[i]记录所有能够从j跳到i的i-j,即k。
共有O(nn)种状态,故空间复杂度是O(nn),每种状态的转移方程时间复杂度O(1),故总时间复杂度O(nn)。

动态规划的细节,方便检查

动态规划的状态表示dp[i]记录所有能够从j跳到i的i-j,即k
动态规划的转移方程对于d[i]中的任意k,看是否存在石头stone[i]+i-1 ,stone[i]+i,stone[i]+i+1,如果存在,则可以跳到此石头。
动态规划的初始状态dp[0]不会被使用,所以不用初始化。dp[1]有一个元素1
动态规划的填表顺序i从小到大。因为只能从小到大跳,可以,确保动态规划的无后效性
动态规划的返回值dp.back()。size()

超时代码

class Solution {
public:
bool canCross(vector& stones) {
if (1 != stones[1])
{
return false;
}
m_c = stones.size();
std::unordered_map<int, int> mValueIndex;
for (int i = 0; i < stones.size(); i++)
{
mValueIndex[stones[i]] = i;
}
vector<vector> dp(m_c);
dp[1].emplace_back(1);
for (int i = 1; i < m_c; i++)
{
for (const auto& k : dp[i])
{
for (int j = max(k - 1, 1); j <= k + 1; j++)
{
const int iNewValue = stones[i] + j;
if (mValueIndex.count(iNewValue))
{
dp[mValueIndex[iNewValue]].emplace_back(j);
}
}
}
}
return dp.back().size();
}
int m_c;
};

不超时代码

超时原因dp[i]中有重复值,用unorder_set除掉重复。
class Solution {
public:
bool canCross(vector& stones) {
if (1 != stones[1])
{
return false;
}
unordered_map<int, int> mPosToIndex;
for (int i = 2; i < stones.size(); i++)
{
mPosToIndex[stones[i]] = i;
}
vector<unordered_set> vPosK(stones.size());
vPosK[1].insert(1);
int k = 1;
for (int i = 1; i < stones.size(); i++)
{
if (stones.size() - 1 == i)
{
return vPosK[i].size();
}
for (auto& k : vPosK[i])
{
int iNewPos = stones[i] + k - 1;
if (mPosToIndex.end() != mPosToIndex.find(iNewPos))
{
vPosK[mPosToIndex[iNewPos]].insert(k - 1);
}
iNewPos++;
if (mPosToIndex.end() != mPosToIndex.find(iNewPos))
{
vPosK[mPosToIndex[iNewPos]].insert(k );
}
iNewPos++;
if (mPosToIndex.end() != mPosToIndex.find(iNewPos))
{
vPosK[mPosToIndex[iNewPos]].insert(k+1);
}
}
}
return true;
}
};

进阶除掉重复

重复的原因 :dp[i]中有x1,x1+1,x1+2 。则x1+1 (x1+1) (x1+2)-1 三者重复。
当dp[j]中有重复的k,说明此时的i相同。由于k=j-i,i是严格递增的,所以k是递减的。由于k是有序的,所以相同的k是挨着一起的。只需要检查前一个元素是否相等,无需判断其它元素。可以在O(1)的时间中避免重复。

class Solution {
public:
	bool canCross(vector<int>& stones) {
		if (1 != stones[1])
		{
			return false;
		}
		m_c = stones.size();
		std::unordered_map<int, int> mValueIndex;
		for (int i = 0; i < stones.size(); i++)
		{
			mValueIndex[stones[i]] = i;
		}
		vector<vector<int>> dp(m_c);
		dp[1].emplace_back(1);
		for (int i = 1; i < m_c; i++)
		{
			for (const auto& k : dp[i])
			{
				for (int j = max(k - 1, 1); j <= k + 1; j++)
				{
					const int iNewValue = stones[i] + j;
					if (mValueIndex.count(iNewValue))
					{
						auto& v = dp[mValueIndex[iNewValue]];
						if (v.empty() || (v.back() != j))
						{
							v.emplace_back(j);
						}
					}
				}
			}
		}
		return dp.back().size();
	}
	int m_c;
};

另外一种方法

前面的方法:第一层循环枚举i,第二层循环枚举k。
下面的方法:第一层循环枚举i,第二层循环枚举j。

class Solution {
public:
	bool canCross(vector<int>& stones) {
		if (1 != stones[1])
		{
			return false;
		}
		m_c = stones.size();
		vector<unordered_set<int>> dp(m_c);
		dp[1].emplace(1);
		for (int i = 2; i < m_c; i++)
		{
			for (int j = 1 ; j < i ;j++ )
			{
				const int iSub = stones[i] - stones[j];
				if (dp[j].count(iSub - 1)|| dp[j].count(iSub)|| dp[j].count(iSub + 1) )
				{//从够从stones[j]跳到stones[i]
					dp[i].emplace(iSub);
				}	
			}
		}
		return dp.back().size();
	}
	int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 **C+

+17**
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

C++ Web框架Drogon初体验笔记

这段时间研究了一下C的Web框架Drogon。从设计原理上面来说和Python的Web框架是大同小异的&#xff0c;但是难点在于编译项目上面&#xff0c;所以现在记录一下编译的过程。下面图是我项目的目录。其中include放的是头文件&#xff0c;src放的是视图文件&#xff0c;static放的是…

机器人技能学习-robosuite-0-入门介绍

文章目录 前言模块介绍实战案例1&#xff1a;从 demo 中创建自己的 env案例2&#xff1a;更换属于自己的物体 前言 资料太少、资料太少、资料太少&#xff0c;重要的事说三边&#xff0c;想根据自己实际场景自定义下机器人&#xff0c;结果发现无路可走&#xff0c;鉴于缺少参…

【unity小技巧】FPS游戏实现相机的偏移震动、武器射击后退和后坐力效果

最终效果 文章目录 最终效果前言相机偏移震动相机震动脚本换弹节点震动 武器射击后退效果武器后坐力效果完结 前言 关于后坐力之前其实已经分享了一个&#xff1a;FPS游戏后坐力制作思路 但是实现起来比较复杂&#xff0c;如果你只是想要简单的实现&#xff0c;可以看看这个&…

类与对象中篇

前言 在上篇我们讲解了类与对象的基础框架&#xff0c;中篇我们将讲解类与对象的基本内容&#xff0c;即类的六个默认成员函数。 一、类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 问题&#xff1a; 空类中真的什么都没有吗&#xff1f; 答案是&a…

软件测试必会:cookie、session和token的区别

今天就来说说session、cookie、token这三者之间的关系&#xff01;最近这仨玩意搞得头有点大&#x1f923; 01、为什么会有它们三个 我们都知道 HTTP 协议是无状态的&#xff0c;所谓的无状态就是客户端每次想要与服务端通信&#xff0c;都必须重新与服务端链接&#xff0c;意…

【YOLO系列】 YOLOv4之Mish函数

一、简述 一个新的state of the art的激活函数&#xff0c;ReLU的继任者。 Diganta Misra在 “Mish: A Self Regularized Non-Monotonic Neural Activation Function”论文中介绍了Mish这个新的深度学习激活函数&#xff0c;指出该函数在准确度上比Swish&#xff08;0.494%&…

资深大佬养成之路:Java中关于List集合选择与使用

目录 1、前言 2、List集合的概念和作用 2.1 什么是List集合 2.2 List集合的作用 2.3 List集合的特点 3、ArrayList和LinkedList的区别 3.1 ArrayList的特点和适用场景 3.2 LinkedList的特点和适用场景 3.3 如何选择ArrayList还是LinkedList 4、List集合的常用操作 4…

Java IO学习和总结(超详细)

一、理解 I/O 是输入和输出的简写&#xff0c;指的是数据在计算机内部和外部设备之间的流动。简单来说&#xff0c;当你从键盘输入数据、从鼠标选择操作&#xff0c;或者在屏幕上看到图像&#xff0c;这些都是 I/O 操作。它就像是计算机与外部世界沟通的桥梁&#xff0c;没有 I…

harmony开发之状态state修饰器的使用

来自官方开发文档&#xff0c; State装饰的变量&#xff0c;或称为状态变量&#xff0c;一旦变量拥有了状态属性&#xff0c;就和自定义组件的渲染绑定起来。当状态改变时&#xff0c;UI会发生对应的渲染改变。 在状态变量相关装饰器中&#xff0c;State是最基础的&#xff0…

更改邮箱发件人

更改邮箱发件人 未更改前发件人显示为发件人的邮箱地址 这里以outlook邮箱为例&#xff0c;进行邮箱发件人的更改 1.点击左上角“文件”选项 2.打开“账户设置”下拉菜单中的“账户设置” 3.选择“电子邮件”&#xff0c;点击该栏下的“更改”选项 4.在弹出页面中修改你…

<软考高项备考>《论文专题 - 56 进度管理(7) 》

10 历年真题解析 10.1 格式 背景500字1-2段 过渡段150字左右1段 一、规划进度管理…【随便写&#xff0c;正常写即可】 二、定义活动…【随便写&#xff0c;正常写即可】 三、排列活动顺序…【随便写&#xff0c;正常写即可】 四、估算活动持续时间…【随便写&#xff0c;正常…

redhat+ oracle 11.2.0.4 RAC 搭建 dataguard

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; redhat oracle 11.2.0.4 RAC 搭建 dataguard 1.安装环境 主机名 OS DB SID db_name db_unique_name rac1 Redhat7 11.2.0.4 orcl1 orcl o…

【OpenCV学习笔记05】- 鼠标作为画笔

内容 学习如何用OpenCV处理鼠标事件您将学习以下功能&#xff1a;cv.setMouseCallback() 简单的示例 这里&#xff0c;我们创建一个简单的程序&#xff0c;在图像的任何位置双击在上面画一个圆。 首先我们创建一个鼠标回调函数&#xff0c;该函数在鼠标事件发生时执行。鼠标…

从txt文档里筛选出每行重复数据字符,并保存到新的txt文档

从txt文档里筛选出每行重复数据字符&#xff0c;并保存到新的txt文档 input_file rD:\pythonXangmu\quchong\input_file2.txt #原始文档 #output_file output.txt#重复内容记录文档 output_file rD:\pythonXangmu\quchong\output2.txt#绝对路径&#xff0c;解决报错找不到文…

一篇文章认识微服务中Eureka的原理和服务注册与发现

目录 1、认识Eureka 2、Eureka原理 2.1 和Dubbo架构对比&#xff1a; 2.2 三大角色 3、微服务常见的注册中心 3.1 Zookeeper 3.2 Eureka 3.3 Consul 3.4 Nacos 3.5 区别 1、认识Eureka Netflix 在设计Eureka 时&#xff0c;遵循的就是AP原则。 CAP原则又称CAP定理…

TagTextView 行内标签TextView

效果 效果如下&#xff0c;可以解析xml中配置的drawableStart &#xff0c;然后将这个drawable显示在一行内。下一个开始。从这个drawable开始。 代码 MaxLengthTextView 是我另外一个自定义view MaxLengthTextView 如果内容超过xml中maxLength属性定义的文字数量时&#x…

揭秘加密货币周期:如何通过顶级代币指标洞察市场变化

作者&#xff1a;stellafootprint.network 加密生态领域如大海般波涛汹涌&#xff0c;如何在这片海域中稳稳航行&#xff1f;关键在于把握市场周期的脉搏。顶级代币的几个核心指标&#xff0c;正是我们窥探市场周期的窗口。 领先的区块链分析平台跟踪的关键代币指标包括&…

什么软件能查出微信聊天记录(3款实用工具盘点!)

微信聊天记录往往记录这很多重要的客户信息&#xff0c;一个不小心可能就会删除&#xff0c;或者员工可以隐藏一些重要的信息&#xff0c;那么此时此刻我们就需要一款&#xff0c;能查处微信聊天记录的工具。 今天就给大家盘点三款&#xff1a; 1、微信电脑端备份 通过在电脑…

MySql01:初识

1.mysql数据库2.配置环境变量3. 列的类型和属性&#xff0c;索引&#xff0c;注释3.1 类型3.2 属性3.3 主键(主键索引)3.4 注释 4.结构化查询语句分类&#xff1a;5.列类型--表列类型设置 1.mysql数据库 数据库&#xff1a; ​ 数据仓库&#xff0c;存储数据&#xff0c;以前我…

基于模块自定义扩展字段的后端逻辑实现(一)

目录 一&#xff1a;背景介绍 二&#xff1a;实现过程 三&#xff1a;字段标准化 四&#xff1a;数据存储 五&#xff1a;数据扩展 六&#xff1a;表的设计 一&#xff1a;背景介绍 最近要做一个系统&#xff0c;里面涉及一个模块是使用拖拉拽的形式配置模块使用的字段表…