Given an array of integers arr and an integer d. In one step you can jump from index i to index:

i + x where: i + x < arr.length and 0 < x <= d.
i - x where: i - x >= 0 and 0 < x <= d.
In addition, you can only jump from index i to index j if arr[i] > arr[j] and arr[i] > arr[k] for all indices k between i and j (More formally min(i, j) < k < max(i, j)).

You can choose any index of the array and start jumping. Return the maximum number of indices you can visit.

Notice that you can not jump outside of the array at any time.

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-v
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

-----------------------------------------------------------------------------------------------------------------

【难点分析】

某位置可访问的最多节点数与周围i-x ~ i+x的节点有关,容易想到用动态规划的方法来做。然而一个节点能到达的节点数不仅与左半边节点相关,也与右半边节点相关,所以不能简单的从0开始遍历整个数组。

【解决方案】:

方案一:

对可以访问的节点数从1开始进行遍历,即dp[i][j] 表示第i个节点是否可以访问j个节点,直到左右dp[i][j]都为false时循环结束。对每一个dp[i][j],寻找他的左边及右边满足条件的节点中可以使他为true的节点,一旦发现后便退出循环。

class Solution {
public:
int maxJumps(vector<int>& arr, int d) {
int n = arr.size();
vector<vector<bool>> dp(n, vector<bool>(n+, false));
for(int i = ; i < n; ++i)
dp[i][] = true;
for(int jp = ; jp <= n; jp++) {
bool flag = false;
for(int i = ; i < n; ++i) {
if(!dp[i][jp-]) continue;
for(int j = i-; j >= && i-j <= d && arr[j] < arr[i]; j--) {
if(dp[j][jp-]) {
dp[i][jp] = true;
//cout << i << ", " << jp << endl;
flag = true;
break;
}
}
if(dp[i][jp]) continue;
for(int j = i+; j < n && j-i <= d && arr[j] < arr[i]; j++) {
if(dp[j][jp-]) {
dp[i][jp] = true;
//cout << i << ", " << jp << endl;
flag = true;
break;
}
}
}
if(!flag) return jp;
}
return n+;
}
};

时间复杂度:O(d*n^2)

方案二.

对于需要根据未知状态来确定当前状态值的动态规划问题,可以用记忆化搜索方法来解决,即如果dp[i] = func(dp[j]), 若dp[j]还未求出,则先去求dp[j]。这种方法要注意的是是否存在循环的状况,即类似于dp[i] = func(dp[j]), dp[j] = func(dp[k]), dp[k] = func(dp[i])。

因为本题中如果dp[i]需要由dp[j]来求得,则arr[j]必小于arr[i],dp[j]不可能由dp[i]直接或间接决定。

class Solution {
private:
vector<int> jmp;
public:
void dfs(vector<int>& arr, int id, int d) {
if(jmp[id] != ) return;
jmp[id] = ;
for(int t = ; t <= d && id+t < arr.size() && arr[id+t] < arr[id]; t++) {
dfs(arr, id+t, d);
jmp[id] = max(jmp[id], jmp[id+t]+);
}
for(int t = ; t <= d && id-t >= && arr[id-t] < arr[id]; t++) { dfs(arr, id-t, d);
jmp[id] = max(jmp[id], jmp[id-t]+);
} }
int maxJumps(vector<int>& arr, int d) {
int n = arr.size();
jmp.resize(n, );
for(int i = ; i < n; ++i) {
dfs(arr, i, d);
}
return *max_element(jmp.begin(), jmp.end());
}
};

时间复杂度: O(n*d) //每一个节点只需计算一次,需要与i-d ~ i+d的节点进行对比

Leetcode相似题目还有:135

最新文章

  1. jquery插件开发
  2. Mac下修改Hosts文件工具——Gas Mask
  3. windows下安装nodejs尝尝鲜
  4. css遇到的问题
  5. hosts文件导致打不开某些网站
  6. 错误“Unexpected namespace prefix &quot;xmlns&quot; found for tag LinearLayout”的解决方法
  7. How to setup ELM327 Bluetooth WiFi for Android software Torque
  8. Alpha 版本测试和发布说明
  9. 总结安装webpack过程中遇到的错误及解决方案
  10. Django模型操作常用方法
  11. 自动化测试基础篇--Selenium select下拉框
  12. 『TensorFlow』流程控制
  13. file相关方法
  14. 1.5.4、CDH 搭建Hadoop在安装之前(定制安装解决方案---配置自定义Java主目录位置)
  15. Leetcode——413. 等差数列划分
  16. Android Studio常用快捷键 - 转
  17. Luogu P2055 [ZJOI2009]假期的宿舍
  18. java对文件的操作
  19. redis的使用及方法
  20. QT-2D编程

热门文章

  1. c++指定输出小数的精度
  2. 2019-2020-1 20199328《Linux内核原理与分析》第三周作业
  3. linux find string in files
  4. Task Scheduler Error Message: 80041318
  5. java 8中构建无限的stream
  6. 【JAVA基础】03 Java语言基础
  7. 使用@vue/cli搭建vue项目开发环境
  8. jmeter的教学视频
  9. Bind+DLZ+MySQL智能DNS的正向解析和反向解析实现方法
  10. 程序员还在用360,腾讯电脑管家清理注册表,清理垃圾?只能说你太low