解法1
读题分析,这是一个固定数组,数组的元素不能随便移动,大概率是扫描遍历数组求解最优值。再进一步分析,可以采取动态规划思想,我们从尾部往前推,对于最后一个元素也就是下标为n-1的元素,它肯定是由前面某个下标为k的元素跳跃了x步,其中k<n-1且x<nums[k],分析到这,状态迁移方程也就很容易列出来了。
状态方程为
dp[i]=dp[k]+1(k<i且k+nums[k]>=i)
dp[0]=0
代码如下:
53
class Solution {
public:
int jump(vector<int>& nums) {
int length=nums.size();
int *dp=new int[length];
for(int i=0;i<length;i++)
{
dp[i]=i;
}
for(int i=0;i<length-1;i++)
{
for(int j=1;j<=nums[i];j++)
{
if(i+j<length)
{
dp[i+j]=dp[i]+1<dp[i+j]?dp[i]+1:dp[i+j];
}
}
}
return dp[length-1];
}
};
时间复杂度O(n²)空间复杂度O(n)
解法2
看了官方答案,贪心算法时间复杂度和空间复杂度可以进一步地减少为O(n)和O(1),主要思路就是不断进行贪心计算,计算跳1步最远能走到哪个位置,跳2步最远能走到哪个位置…直到最远位置覆盖最后一个元素。这样所得结果即为步数的下界,也就是最优解。
代码如下:
class Solution {
public:
int jump(vector<int>& nums) {
int step=0;//最小步数
int end=0;//最远边界
int tmax=0;//临时值,用于计算最远边界
int length=nums.size();
for(int i=0;i<length-1;i++)
{
tmax=i+nums[i]>tmax?i+nums[i]:tmax;
if(i==end)
{
end=tmax;
step++;
}
}
return step;
}
};
本文探讨了一种固定数组的跳跃游戏问题,分别使用动态规划和贪心算法来寻找最少步数解。动态规划方法通过状态转移方程实现,时间复杂度为O(n²);而贪心算法通过不断更新最远边界,达到O(n)的时间复杂度。两种方法在空间复杂度上分别为O(n)和O(1)。
1029

被折叠的 条评论
为什么被折叠?



