记一次动态规划和贪心的刷题经历
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvb8zs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如何理解动态规划和贪心的解题思路?
**TODO...
动态规划
dp数组维护第i位可以进行的最远跳数。
public boolean canJump(int[] nums) {
if(nums.length == 1){
return true;
}
int[] dp = new int[nums.length - 1];
dp[0] = nums[0];
for(int i = 1; i < dp.length; i++){
if(dp[i - 1] == 0){
return false;
}
if(nums[i] >= nums.length - 1 - i){
return true;
}
dp[i] = Math.max(nums[i], dp[i - 1] - 1);
}
return (dp[dp.length - 1] >= 1);
}
每次使用dp数组只和前一位元素交互,所以不需要一个数组,只需维护前一位元素作为一个变量即可。但注意,优化只是优化了使用逻辑,动态规划还是把每步的最优解存储了下来供下一步利用。
public boolean canJump(int[] nums) {
if(nums.length == 1){
return true;
}
int preJump = nums[0];
for(int i = 1; i < nums.length - 1; i++){
if(preJump == 0){
return false;
}
if(nums[i] >= nums.length - 1 - i){
return true;
}
preJump = Math.max(nums[i], preJump - 1);
}
return (preJump >= 1);
}
贪心
只维护一个表示当前能达到的最远距离的全局变量,通过不断遍历数组更新这个值。
public boolean canJump(int[] nums) {
if(nums.length == 1){
return true;
}
int preJump = nums[0]; //当前能跳的的最远下标
for(int i = 1; i < nums.length; i++){
if(preJump < i){
return false; //最远下标达不到当前下标
}
preJump = Math.max(nums[i] + i, preJump);
if(preJump >= nums.length - 1){ //更新最远下标
return true;
}
}
return false;
}
浙公网安备 33010602011771号