leetcode55.跳跃游戏:https://blog.csdn.net/zhangjiaji111/article/details/120659495
方法一:贪心
具体思路:不考虑跳到哪一个,只考虑跳到该位置能跳到的最远的距离
class Solution {
public:
int jump(vector<int>& nums) {
int cur_max = 0, end = 0, n = nums.size(), ans = 0;
for (int i = 0; i < n - 1; ++i) { //
cur_max = max(cur_max, i + nums[i]);
if (cur_max >= n - 1) return ans + 1;
if (i == end) {
ans++;
end = cur_max; //刚开始跳一次最远就是0+nums[0]
}
}
return ans;
}
};
易错点:
1:代码上需要注意写成n-1,否则最远跳到最后一个位置时会多跳一次
2:如果cur_max >= n - 1时 return ans+1,因为表示下一跳能跳到的最远,还需要跳一次
方法二:贪心(能够知道记录下一跳能跳的位置)
具体思路:当前的位置跳的位置为:下下次可以跳得更远的位置,通过局部最优得到全局最优解。
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size(), ans = 0, pos = 0;
while (pos < n - 1) {
if (pos + nums[pos] >= n - 1) return ans + 1;
int max_pos = pos + 1;
for (int i = pos + 1; i <= pos + nums[pos]; ++i) {
if (i + nums[i] > max_pos + nums[max_pos]) {
max_pos = i;
}
}
pos = max_pos;
ans++;
}
return ans;
}
};
细节理解:
max_pos能初始化为pos+1的原因:不可能跳到0的位置,因为题目说总是可以到达最后一个位置
方法二:dp
具体思路:
dp[i]表示从nums[0]跳到nums[i]的最少步数
转移方程:dp[i]=(能跳到nums[i]的位置的最少步数)+1,即得到dp[i]后,对dp[i+1]到dp[i+nums[i]]进行更新,(正向思考代码比较好写
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, INT_MAX);
dp[0] = 0;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j <= i + nums[i] && j < n; ++j) {
dp[j] = min(dp[j], dp[i] + 1);
}
}
return dp[n - 1];
}
};
易错点:j可能会越界,加上&& j < n