题目描述:
给你一个非负整数数组 nums
,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true
;否则,返回 false
。
经典跳跃小游戏,简单的dp缓存表最好想了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int [] dp2; public boolean canJump (int [] nums) { dp2 = new int [nums.length]; return f(nums, 0 ); } public boolean f (int [] nums, int index) { if (index > nums.length - 1 ) return false ; if (dp2[index] != 0 ) return dp2[index] > 0 ; if (index + nums[index] >= nums.length - 1 ) return true ; boolean res = false ; for (int i = 1 ; i <= nums[index]; i++) { res = res | f(nums, index + i); } dp2[index] = res ? 1 : -1 ; return res; }
改动态规划实现 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public boolean canJump2 (int [] nums) { boolean [] dp = new boolean [nums.length]; dp[nums.length - 1 ] = true ; for (int i = nums.length - 1 ; i >= 0 ; i--) { if (i + nums[i] >= nums.length - 1 ) { dp[i] = true ; } else { for (int j = i + 1 ; j <= i + nums[i]; j++) { if (dp[j]) { dp[i] = true ; break ; } else { j += nums[j]; } } } } return dp[0 ]; }
额外的,贪心实现:
既然题目要求我们到达最后一个,实际上就是要我们走的越远越好,即当前位置能跳的距离和前面最远的距离的较大值即为当前位置的最远距离,只要大于数组长度就返回true
,反之到不了就返回false
1 2 3 4 5 6 7 8 9 public boolean canJump3 (int [] nums) { int max=0 ; for (int i = 0 ; i <= max; i++) { max = Math.max(max, i+nums[i]); if (max>=nums.length-1 )return true ; } return false ; }