leetcode 跳躍遊戲系列
阿新 • • 發佈:2020-06-29
55. 跳躍遊戲能跳一個範圍,貪心
class Solution { public: bool canJump(vector<int>& nums) { int m = 0; //每次拓展最右端點,大於nums.size()-1時返回 for(int i = 0; i < nums.size() ;i++){ if(i <= m) m = max(m, i + nums[i]); if( m >= nums.size() - 1) return true; }return false; } };
45. 跳躍遊戲 II 能跳一個範圍,求跳躍數目,可用貪心
class Solution { public: int jump(vector<int>& nums) { if(nums.size() == 1) return 0; int m = 0; int cnt = 0; int i = 0; //在一的基礎上增加計數,每次到達上一次的最右端點時加一 while( i < nums.size()){int newm = 0; while(i <= m){ newm = max(i + nums[i], newm); i++; } m = newm; cnt++; if(m >= nums.size() - 1) return cnt; } return -1; } };
1306. 跳躍遊戲 III跳兩個點,dfs
class Solution { public: vector<int> vis; bool canReach(vector<int>& arr, int start) { vis.resize(arr.size(),0); return dfs(arr,start); } bool dfs(vector<int>& arr, int start){ if(start < 0 || start >= arr.size() || vis[start]) return false; if(arr[start] == 0) return true; vis[start] = 1; return dfs(arr, start + arr[start]) || dfs(arr,start - arr[start]); } };
1345. 跳躍遊戲 IV可調一些點,bfs,hash
class Solution { public: int minJumps(vector<int>& arr) { int n = arr.size(); if(n == 1) return 0; vector<int> vis(n,0);//用來記錄是否訪問過 int depth = 0; //用hash表來記錄相同的值 unordered_map<int,vector<int>> mp; for(int i = 0; i < n; i++) mp[arr[i]].push_back(i); queue<int> q; q.push(0);vis[0] = 1; while(q.size()){ int len = q.size(); while(len--){ int t = q.front(); q.pop(); if(t == n-1) return depth; //右跳 if(t + 1 < n && !vis[t+1]) q.push(t+1),vis[t+1] = 1; //左跳 if(t - 1 >= 0 && !vis[t-1]) q.push(t-1),vis[t-1] = 1; //相同的值 if(mp.count(arr[t])){ for(int x:mp[arr[t]]){ if(x != t){ q.push(x);vis[x] = 1; } } mp.erase(arr[t]); } } depth++; } return -1; } };
1340. 跳躍遊戲 V可跳一些點,求最值問題:記憶化dfs,dp
class Solution { public: vector<int> dp; int maxJumps(vector<int>& arr, int d) { int ans = 0; dp.resize(arr.size(),-1); for(int i = 0; i < arr.size(); i++) ans = max(ans, dfs(arr,i,d)); return ans; } //dfs記憶化 int dfs(vector<int>& arr, int start,int& d){ //遞迴出口 if(dp[start] != -1) return dp[start]; int res = 1; //向左跳 for(int i = start - 1;i >= 0 && i >= start - d; i--){ if(arr[i] < arr[start]) res = max(res,dfs(arr,i,d) + 1); else break; } //向右跳 for(int i = start + 1; i < arr.size() && i <= start + d; i++){ if(arr[i] < arr[start]) res = max(res,dfs(arr,i,d) + 1); else break; } //記憶 dp[start] = res; return res; } };