Leetcode 55. 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.

Example 1:

Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

Example 2:

Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum
             jump length is 0, which makes it impossible to reach the last index.

Solution 1 (基于动态规划)

75 / 75 test cases passed.
Status: Accepted
Runtime: 756 ms
Submitted: 22 minutes ago

class Solution {
public:
    bool canJump(vector<int>& nums) {
        // true : can reach final
        // false : cannot reach
        vector<bool> states(nums.size(), false);
        states[states.size()-1] = true;
        for (int i = states.size() - 1; i >= 0; i--) { 
            for (int len = nums[i]; len > 0; len--) { // from 1 to nums[i]
                if (states[i + len] == true) {
                    states[i] = true;
                    break;
                }
            }
        }
        return states[0];
    }
};

题解

我们建立了一个布尔数组states[],代表当前下标位置的点能否达到最后一个点。比如如果第一个点可以到达最后一个点的话,那么它被标为states[0]=true

可以从最后一个点开始算:

  1. 首先,最后一个点可以到达自身,我们把它标为true
  2. 往前遍历,如果当前点i在本身可达范围(nums[i])内,有一个states被标为true的点,那么说明它可以到达一个可达末尾的点,那么明显它可以通过跳到这个点来到达末尾,所以它也被标为states[i]=true
  3. 继续遍历到i == 0,我们就得到了0是否可达的信息(即states[0])

分析

复杂度感觉不太好分析,外层是一次O(n)的循环,内层主要取决于nums[i]的大小(可以理解为O(nums[i])。

我们假设mnums数组元素的平均数,那么算法的时间复杂度是O(nm)

(当然,我们加入了满足条件直接break;的语句之后,复杂度可能略小一点,但是小的有限,毕竟跑了756ms)。

空间复杂度简单了,一个states数组,O(n)


Solution 2 (基于贪心算法)

75 / 75 test cases passed.
Status: Accepted
Runtime: 8 ms
Submitted: 35 minutes ago

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int furthestReachablePostion = 0;
        for (int i = 0; i < nums.size(); i++) {
            furthestReachablePostion = max (furthestReachablePostion-1, nums[i]);
            if (furthestReachablePostion + i >= nums.size() - 1) return true;
            else if (furthestReachablePostion <= 0) return false;
        }
        return true;
    }
};

题解

经营一个整型的值furthestReachablePostion ,表示从当前位置开始,最远可达的距离。

比如,输入为[3,2,1,0,4],位置0的最远可达就是3

我们可以考虑,从前往后遍历,每个点处的furthestReachablePostion就是上一个位置的furthestReachablePostion-1,或者当前位置的最远可达nums[i]

  • 如果当前位置的最远可达furthestReachablePostion 加上当前位置 i,大于等于末尾的位置,那么我们可以说这个点可达末尾。

  • 如果furthestReachablePostion<=0,那么我们可以说它不可达,因为已经无法离开当前点了。

分析

时间复杂度:O(n),只使用了一次遍历。

空间复杂度:O(1),只是用了一个变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值