LeetCode No.45 JumpGame 2 题解
来源:互联网 发布:4g网络能玩英雄联盟吗 编辑:程序博客网 时间:2024/05/21 01:31
LeetCode No.45 JumpGame 2 题解
题目描述
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given arrayA = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
Note:
You can assume that you can always reach the last index.
题目分析
题目的大概意思就是给出一个从每个点最多能向前跳的步数, 问至少需要多少步能够跳到数组尾端。
这个最多要引起注意。 之前没有仔细思考, 认为这是一道DP题。 不过这仍不失为一种解法(虽然时间复杂度来说不够好)
那么首先看DP是怎么解的。
方法一 DP求解
首先我们注意到这道题显然是具有一定的最优子问题结构的。即可以通过某种局部最优的情况下进行状态转移达到
一个全局最优。
状态转移方程也十分显然。如下: step[n + k] = min(step[n + k], step[n] + 1), for any k = 1,2,... , a[n]
时间复杂度为:O(n * k) , 其中 k
为每个点最长步数的平均值。
由于实际实现不复杂, 加上不是好的解法, 就不贴代码了(事实上我开始这么写完拿去Judge发现TLE了 :)
方法二 贪心求解
首先来看DP是在什么情况下表现比较糟糕的。 即每个点的步数都很大时, 时间复杂度退化为(n * n).再来考虑为什么会复杂度高(即看是否存在着重复运算)
举一个简单的例子: a[n] = [6,5,4,3,2,1,1,1]
这个例子几乎就是造成DP超时的例子的简化版。
不难发现其实造成了大量的不必要计算。 比如在处理完a[0]
之后, 处理a[1]
时,从a[1 + 1] ~ a[0 + a[0]]
这部分的比较是不必要的, 因为显然之前能够直达的话就不可能更新到更小的值。
于是自然就会产生一个想法:把每一步能够到达的最大点的坐标记录下来,下一步能够到达的最大点的坐标一定只能从当前步数能到达的最大点来得到, 而不是从之前就已经能够到的最大点来得到。
语言描述比较无力, 下面是体现这种想法的主要计算式: max[i] = maximum(nums from max[i - 2] to max[i - 1]);
没有做很严谨的分析, 从直觉上说, 这种做法的主要改进就是记忆化了max数组从而可以设置了搜索的下界。
时间复杂度优化为了O(n)算是一个不错的改进了。
之后我看了一下这道题分类放在Greedy里面,想一下这种方法叫做贪心未尝不可。 但我觉得这种基于状态保存的思想还是更像是DP :)
下面上代码,十分简短。 就喜欢这种代码量不多又有一定trick的题目 ~.~
class Solution {public: int jump(vector<int>& nums) { if (nums.size() == 1) return 0; if (nums[0] >= nums.size() - 1) return 1; int max[nums.size()]; for (int i = 0; i < nums.size(); ++i) { max[i] = 0; } max[0] = 0; max[1] = nums[0]; for (int i = 2; i < nums.size(); ++i) { max[i] = maximum(nums, max[i - 2], max[i - 1]); if (max[i] >= nums.size() - 1) return i; } } int maximum(vector<int> &nums, int st, int ed) { int ans = 0; for (int i = st; i <= ed; ++i) { if (nums[i] + i > ans) ans = nums[i] + i; } return ans; }};
其他细节
- 注意边界条件判断。LeetCode 每道题几乎都有边界的测试。实在服气。
- 像诸如vector这种,还是尽量用引用传递吧。 虽然没试过, 但是感觉不传引用就是TLE…
The End.
- LeetCode No.45 JumpGame 2 题解
- leetcode jumpgame 2
- leetcode JumpGame
- leetcode--JumpGame
- leetcode--JumpGame
- leetcode : jumpgame
- LeetCode JumpGame and JumpGame II
- leetcode解题方案--055--jumpGame
- jumpgame
- leetcode No.1 - two sum题解
- LeetCode No.41 First Missing Positive 题解
- LeetCode No.224 Basic Calculator 题解
- LeetCode No.76 Minimum Window Substring 题解
- leetcode题解(2)
- leetcode-个人题解2
- LeetCode No.233 Number of Digit One 题解
- LeetCode No.84 Largest Rectangle in Histogram 题解
- JumpGame II
- 图的深度优先搜索和广度优先搜索
- 栈(Stack)——后进先出(LIFO)的数据结构(Data Structures)
- 使用PHP导入和导出CSV文件
- 栈和队列的简单应用
- 引用
- LeetCode No.45 JumpGame 2 题解
- Ubuntu安装完后设置root密码
- 深入浅出:线程底层原理
- 字典树的定义
- Java知识复习(线程)
- session和cookie的区别
- Matrix 二维树状数组 区间修改+单点查询
- Android, iPhone、ios安卓 如有要接外包的 这边发不外包任务
- Docker+Spring+Dubbo+ZooKeeper完成服务化RPC实验