当前位置:网站首页>[leetcode每日一题2021/4/29]403. 青蛙过河
[leetcode每日一题2021/4/29]403. 青蛙过河
2022-07-26 10:33:00 【LittleSeedling】
题目来源于leetcode,解法和思路仅代表个人观点。传送门。
难度:困难
时间:40min
TAG:动态规划
题目
一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。
给你石子的位置列表 stones(用单元格序号 升序 表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一块石子上)。
开始时, 青蛙默认已站在第一块石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格 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
思路
先分析题目与示例,发现如下:
- 河流被等分为若干个单元格。如示例1中,河流就被分为18个单元格。示例2中,河流被分为12个单元格。
- 青蛙(除了第一步)每次能够跳跃的单位数 ==
(1)上次跳跃的单位数-1
(2)上次跳跃的单位数
(3)上次跳跃的单位数+1 - 青蛙并不是每个石子都要踩。
动态规划
不是官方动归解法,速度慢了许多。官方解法点我。
如果使用动态规划,我们需要初始化dp数组。
那么,
- dp数组的长度由什么确定?
- dp数组的维度有几维?
- 转移方程如何确定?
根据【提示】,
- stones数组长度<=2000==2*103。如果使用该变量作为dp数组的长度,算法时间复杂度可以使用O(n2)。
- stones[i]<=INT_MAX,如果使用该变量作为dp数组的长度,太大了,空间不够高。
leetcode的算力大概在O(n7~n8)左右。
那么,我们尝试着使用stones数组的长度作为dp数组的长度。
下面画图分析示例1:
【红色】表示每个石子之间的单位数。
【蓝色】表示石子位置。
【黄色】表示成功的跳跃路线。
【玫瑰色】表示失败的跳跃路径。
【橙色】表示到达当前石子的跳跃单位数。
6可以由3=>6,5=>6
8可以由6=>8,5=>8
对于每个状态dp[i],我们的状态从何转移过来?
肯定是由前面dp[0~i-1]之中转移过来的,那么我们遍历前面j=0~i-1的状态,【判断、是否能够转移到dp[i]。
判断条件:
- distance=stones[i] - stones[j]
- 到达状态dp[j]的跳跃单位数jump
- 是否满足jump-1==distance || jump == distance || jump+1 == distance
(这样时间复杂度是O(n2),经过上面的分析,leetcode应该可以接受)
我们需要保存,到达当前状态所跳跃的单位数,因为该变量可能有多个,所以我们对于每个状态dp[i]需要一个数组来记录。
所以,
- dp数组长度由stones长度确定
- dp数组维度为二维
- dp[i]由dp[0~i-1]转移
- 算法时间复杂度估计在O(n2)左右
代码
class Solution {
public:
bool canCross(vector<int>& stones) {
//石子数组长度
int n = stones.size();
/* 超时。 由于【到达dp[j]所跳跃的单位数】可能有多个,如果使用数组依次遍历,时间复杂度可能达到O(n³) */
// vector<vector<int>> dp(n);
// dp[0].push_back({0});
// for(int i=1;i<n;i++){
// for(int j=0;j<i;j++){
// //石子之间的距离
// int distance = stones[i] - stones[j];
// //对于j=[0,i-1],到达dp[j]所跳跃的单位数,判断是否满足条件
// for(auto rj:dp[j]){
// if(distance == rj-1 || distance == rj || distance == rj+1){
// dp[i].push_back(distance);
// }
// }
// }
// }
/* 使用set代替数组。 每次判断只需要3次,减少计算量。 为什么使用long? distance+1可能超出INT_MAX */
vector<unordered_set<long>> dp(n);
dp[0].insert(0);
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
//石子之间的距离
long distance = stones[i] - stones[j];
//对于每个石子的上一步 冲刺距离
if(dp[j].count(distance-1) || dp[j].count(distance) || dp[j].count(distance+1)){
dp[i].insert(distance);
}
}
}
return dp[n-1].size() != 0;
}
};
算法复杂度
时间复杂度: O(n2)。n为stones数组的长度。
空间复杂度: O(n2)。n为stones数组的长度。每个状态 需要记录 【到达当前状态】的所有跳跃数。
下面为官方解法的速度。对比起来,慢了许多。
边栏推荐
- STM32 阿里云MQTT esp8266 AT命令
- Nacos custom service change subscription
- json-c库的简单使用——将json文件转换为struct.
- 分布式锁解决方案之Redis实现
- [C language] named type and anonymous type
- 数据库函数
- centos8(liunx)部署WTM(ASP.NET 5)使用pgsql
- 同步方法中不使用asyncTask<T> 修饰和await获取异步返回值(同步方法中调用异步方法)
- .NET5WTM(ASP.NET Core) PGSql开箱操作
- Listening freely, the next stop of online text traffic competition?
猜你喜欢
The difference between equals and = =
Unit test, what is unit test and why is it so difficult to write a single test
Dynamically determine file types through links
Cause: couldn‘t make a guess for 解决方法
[Halcon vision] Fourier transform of image
Introduction to data analysis | kaggle Titanic mission
Navicat15 MySQL (centos7) connected to local virtual machine
The CLOB field cannot be converted when querying Damon database
【Halcon视觉】图像滤波
2022/07/25------字符串的排列
随机推荐
The reason why go language is particularly slow to develop run and build commands
Li Kou daily question 917
干货likeshop外卖点餐系统开源啦100%开源无加密
.NET 开源框架在工业生产中的应用
QRcode二维码(C语言)遇到的问题
Review of database -- 3. SQL language
【Halcon视觉】图像灰度变化
Review of database -- 1. Overview
[Halcon vision] programming logic
C语言计算日期间隔天数
String null to empty string (what does empty string mean)
json_object_put: Assertion `jso->_ref_count > 0‘ failed.Aborted (core dumped)
移动端H5开发常用技巧总结
Introduction to data analysis | kaggle Titanic mission
Function template parameters (where are the function parameters)
Function templates and non template functions with the same name cannot be overloaded (definition of overloads)
.NET操作Redis String字符串
Navicat15 MySQL (centos7) connected to local virtual machine
【C#语言】具名类型和匿名类型
modelsim 安装教程(应用未安装)