lettcode-跳跃游戏

问题描述

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

示例

输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

代码(c++)

方法一(超时):动态规划

class Solution {
public:
    int jump(vector<int>& nums) {
	int n = nums.size();
    int num=0;
    if(nums.size()==1) return 0;
    for(int i=0;i<n;i++){//全1的情况
        if(nums[i]==1) num++;
        else break;
    }
    if(num==n) return n-1;
    vector<vector<int>> flagdata(n + 1, vector<int>(n + 1,1));
	for (int i = 1; i < n; i++) {
		for (int j = 1; j <= n; j++) {
			if (j + i > n) break;
			int value = nums[j-1];
            if(i>value){
				int mindata = n;
				for (int k = j + 1; k < j+i; k++) {
                    mindata=min(mindata,flagdata[j][k] + flagdata[k][j+i]);
				}
				flagdata[j][j+i] = mindata;
			}
		}
	}
	return flagdata[1][n];
}
};

刚开始是全25000个1的数据过不去,所以就加了一个限定条件,但是后来还是91/92数据失败

方法二(贪心)也是官方题解:

class Solution {
public:
    int jump(vector<int>& nums) {
	int n = nums.size();
    int maxdata=0,end=0;
    int result=0;
    for(int i=0;i<n-1;i++){
        maxdata=max(maxdata,i+nums[i]);//获取当前遍历过程的最远距离(针对上一个end位置之前的所有位置来讲)
        if(i==end){//一个end代表一次跳跃
            end=maxdata;
            result++;
        } 
    }
    return result;
    }
};

采用了贪心策略,时间复杂度是O(n),遍历过程中用end符号记录这一次可以跳的最远距离,在没有到达end之前,计算下一次可以遍历的最远距离

反思

千万别把问题想得太严重,太复杂!!!虽然是一道困难类型的题目,但是思路却很简单!!

你可能感兴趣的:(算法)