$$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Self-defined math definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Math symbol commands \newcommand{\intd}{\,{\rm d}} % Symbol 'd' used in integration, such as 'dx' \newcommand{\diff}{{\rm d}} % Symbol 'd' used in differentiation ... $$

45. 跳跃游戏 II

题目描述查看:https://leetcode-cn.com/problems/jump-game-ii/

  题目的意思是给定一个数组,数组元素表示每次能往前走的最大步数,求到数组末尾最少需要走几步。

1.动态规划(很不幸,超时了)

  • 思路

设dp[i]为跳到第i个位置需要的最少步数。

初始条件,设跳到每个位置的步数都是无穷大。

        for (int i = 1; i < dp.length; i++) {
            dp[i] = Integer.MAX_VALUE;
        }

要知道dp[i]的最少步数,就要知道从哪个位置起跳能到i,遍历数组元素,如果从当前位置j起跳,跳nums[j]步,能跳到i位置,那么dp[j]+1和当前dp[i]比,小的那个就是最少步数。

                if(nums[j] + j >=i)
                    //从j位置能跳到i位置
                    dp[i] = Math.min(dp[i],dp[j]+1);
            }
  • 代码

 1     public int jump(int[] nums) {
 2         int[] dp = new int[nums.length];
 3         for (int i = 1; i < dp.length; i++) {
 4             dp[i] = Integer.MAX_VALUE;
 5         }
 6 
 7         for (int i = 1; i < dp.length; i++) {
 8             for (int j = 0; j < i; j++) {
 9                 if(nums[j] + j >=i)
10                     //从j位置能跳到i位置
11                     dp[i] = Math.min(dp[i],dp[j]+1);
12             }
13         }
14         return dp[nums.length-1];
15     }

 2.贪心

  • 思路

从当前位置i起跳,可以跳到[i+1,nums[i]+i]个候选位置,从i位置起跳后的位置应该是候选位置中能跳的最远的位置。

根据这个思路,设定point指针指向当前位置,maxIndex表示当前位置能起跳到的最远位置。

 1         while(point < nums.length){
 2             int maxIndex = nums[point] + point;
 3             //如果最远位置能到终点,直接跳到终点
 4             if(maxIndex >= nums.length -1){
 5                 step++;
 6                 break;
 7             }
 8             //max保存候选位置能到的最远位置
 9             int max = 0;
10             for (int i = point; i <= maxIndex; i++) {
11                 if(i+nums[i] >= max){
12                     point = i;
13                     max = i+nums[i];
14 
15                 }
16             }
17             step++;
18         }
  • 边界条件

注意这块的等号,多个候选位置能到同一个最远距离的时候,point指向后边的候选位置。

if(i+nums[i] >= max)
  • 代码

 1     public int jump(int[] nums) {
 2         if(nums.length == 1)
 3             return 0;
 4         int point = 0;
 5         int step = 0;
 6         while(point < nums.length){
 7             int maxIndex = nums[point] + point;
 8             if(maxIndex >= nums.length -1){
 9                 step++;
10                 break;
11             }
12             int max = 0;
13             for (int i = point; i <= maxIndex; i++) {
14                 if(i+nums[i] >= max){
15                     point = i;
16                     max = i+nums[i];
17 
18                 }
19             }
20             step++;
21         }
22         return step;
23     }

 

posted @ 2020-04-04 15:10  V丶vvv  阅读(186)  评论(0编辑  收藏  举报