leetcode上中等难度的跳跃问题总结
【题目1】
给定一个非负整数数组nums,你最初位于数组的第一个下标,数组中的每个元素都代表你在该位置可以跳跃的最大长度判断你是否能够达到最后一个位置。
方法1
class Solution {
public:
bool canJump(vector<int>& nums) {
int maxPos = 0;
for(int i = 0; i < nums.size(); ++i){
if(i <= maxPos){ //如果当前坐标值i 小于 目前达到的最大坐标值
maxPos = max(maxPos ,i+nums[i]); //则 更新 当前跳跃的最右边的下标
}
else{ //如果i超过当前最大能达到的最大坐标值
return false;
}
}
return true;
}
};
方法2
class Solution {
public:
bool canJump(vector<int>& nums) {
int maxPos = 0;
for(int i = 0; i < nums.size(); ++i){
if(i <= maxPos){ //如果当前坐标值i 小于 目前达到的最大坐标值
maxPos = max(maxPos ,i+nums[i]); //则 更新 当前跳跃的最右边的下标
if(maxPos >= nums.size()-1){
return true;
}
}
}
return false;
}
};
【题目2】
给定一个非负整数数组nums,你最初位于数组的第一个下标,数组中的每个元素都代表你在该位置可以跳跃的最大长度,求出到达最后一个位置所需要的最少的跳跃次数。
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, n+2);
dp[0] = 0;
for(int i = 0; i < n; ++i){
for(int jumpStep = 1; jumpStep <= nums[i]; ++jumpStep){ //在i处跳跃的步长
if(i+jumpStep < n){
dp[i+jumpStep] = min(dp[i+jumpStep], dp[i]+1);
}
}
}
return dp[n-1];
}
};
【题目3】
这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i],请你判断自己是否能够跳到对应元素值为 0 的任一下标处。
class Solution {
private:
bool flag = false;
void dfs(vector<int>& arr, vector<bool>& vis, int i){
if(flag){
return;
}
if(arr[i] == 0){ //判断位置i对应的值是否是0
flag = true;
return;
}
int a[2] = {i + arr[i], i - arr[i]};
for(int i = 0; i < 2; ++i){
if(a[i] >= 0 && a[i] <= arr.size()-1 && !vis[a[i]] && !flag){
vis[a[i]] = true;
dfs(arr, vis, a[i]);
vis[a[i]] = false;
}
}
}
public:
bool canReach(vector<int>& arr, int start) {
vector<bool> vis(arr.size(), false);
vis[start] = true;
dfs(arr, vis, start);
return flag;
}
};
【题目4】
class Solution {
public:
int maxResult(vector<int>& nums, int k) {
int n = nums.size();
// 优先队列中的二元组即为 (f[j], j)
priority_queue<pair<int, int>> q;
q.emplace(nums[0], 0);
int ans = nums[0];
for (int i = 1; i < n; ++i) {
// 堆顶的 j 不满足限制
while (i - q.top().second > k) {
q.pop();
}
ans = q.top().first + nums[i];
q.emplace(ans, i);
}
return ans;
}
};