Leetcode: Jump Game

本文介绍如何通过动态规划解决跳跃游戏问题,提供两种不同的动态规划算法,并详细解释每种算法的时间复杂度和空间复杂度。重点在于理解动态规划在解决此类问题中的应用和优势。
Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

难度:90,这是一道DP的题目,当然也可以不用DP的思路有一个聪明的算法来取巧。参看了一下网上思路

这也是一道比较经典的动态规划的题目,不过不同的切入点可能会得到不同复杂度的算法,比如如果维护的历史信息是某一步是否能够到达,那么每一次需要维护当前变量的时候就需要遍历前面的所有元素,那么总的时间复杂度就会是O(n^2)。所以同样是动态规划,有时候也会有不同的角度,不同效率的解法。

这道题的特殊之处在于Values of each array element indicates the "maximum" jump length.  Which means if the value is 3, then it can jump 1 step, 2 steps or 3 steps. 所以只要考虑最大能到的点就好了。举个例子如果第五号位置上的数无法到达,那么第六号也无法到达,反过来,如果第六号能到达,那第五号元素四号三号等等也是一定可达的。所以只要考虑每次最远能到的点就好了

DP思路:用“局部最优和全局最优解法”,我们维护一个到目前为止能跳到的最远距离,以及从当前位置一步能跳到的最远距离。局部最优local=A[i]+i,而全局最优则是global=Math.max(global, local)。递推式出来了,代码就比较容易实现了。因为只需要一次遍历时间复杂度是O(n),而空间上是O(1)。

 1 public class Solution {
 2     public boolean canJump(int[] A) {
 3        if (A == null || A.length == 0) {
 4            return false;
 5        }
 6        
 7        int global = 0;
 8        for (int i=0; i<=global && i<A.length; i++) {
 9            global = Math.max(A[i]+i, global);
10        }
11        if (global < A.length-1) return false;
12        else return true;
13     }
14 }

另外有一个思路,只看零点he only factor that would impact the result is the value of 0.  (if there is no 0 element, end index must be able to reach, like by jumping 1 step each time). 

Therefore, we only need to focus on the value 0 elements. In order to jump through the 0 element, at least one element that is prior to the examining 0 element need to have the "ability" to jump further than the distance between this element and the examining 0 element.  For example, in array [2,3,1,0,4], the 3rd element (1) cannot jump through the 0 element, but the 2nd element (3) can jump through the 0 element.  Accordingly, if no prior element can jump through the 0 element, program can return false.

这个思路也是O(N^2)时间复杂度,但是比较巧妙

 1 public class Solution {
 2     public boolean canJump(int[] A) {
 3         if(A.length == 1) return true;
 4         
 5         int count = 0;
 6         for(int i=A.length-2; i>=0; i--){// check all the 0 elements existing in the array
 7             if(A[i] == 0) {
 8                 // flag indicates if there is any prior element can jump through this 0 element
 9                 boolean jumpFlag = false;
10                 for (int j=i-1; j>=0; j--){
11                     if(A[j]>i-j) { // jth element is able to jump through this 0 element
12                         jumpFlag = true; 
13                         break;
14                     }
15                 }
16                 if(jumpFlag == false) return false; // no prior elements can jump through this 0 element
17             }
18         }
19         return true;
20     }
21 }

 

转载于:https://www.cnblogs.com/EdwardLiu/p/3967610.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值