leetcode 55. Jump Game

这里写图片描述

 题目的要求是给出一个数组,数组中每个元素的数值代表可以从这个下标“跳跃”到的最大距离(注意是最大,也就是说可以跳小于这个距离)。初始下标是0,问能否跳到数组最大的下标。
 其实第一眼看到这道题,我以为是要用分治算法或者构建一棵树之类的,讲真,用树真的可以做的好吗……后来我的想法是,从下标0开始,记录它能到达的所有下标,然后再按顺序访问这些下标,看它们能跳转到哪里,能否跳转到最大的下标。所以我一开始采用了set来存储,利用set元素的唯一性,把能到的下标都插进去,直到能够跳到最后或者set遍历完还没到最后,结果75个测试中恰恰有个巨长的测试会超时,其他都通过。明显我的想法虽然离目标不远,但还是太复杂了。于是我决定每次插入前先判断能否使得set中元素增加(能到达的最大下标增大),不能就不处理了。于是我第一次pass了这道题,但只超过了9%的提交,明显有待改进。
 以下是第一次成功的代码,仅仅是留个纪念,因为后面的方法更简洁
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int asize = nums.size();
        if (asize == 0) return false;
        if (asize == 1) return true;
        set<int> myset;
        myset.insert(0);
        set<int>::iterator it = myset.begin();
        int max = 0;
        while(it != myset.end()) {
            if (max >= asize - 1) return true;
            //  由于set内部的值从小到大,所以不用担心越界问题,因为越界之前已经返回true
            int diff = *it + nums[*it] - max;
            if (diff > 0) {
                for (int i = 1; i <= diff; i++) {
                    myset.insert(max + i);
                }
                max = *it + nums[*it];
            }
            it++;
        }
        return false;
    }
};
 为了寻求更快速的方法,我查看了讨论区,并且发现我把能到达的元素全部记录起来完全是多余的,因为能跳到的最大下标之前的所有下标都是可达的,所以只记录当前最大下标就行了。于是简化之后,超过了82.74%的提交。
 改进后的代码如下:
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int asize = nums.size();
        int reach = 0;  //  记录当前能到达的最大下标
        int i = 0;
        //  从0开始遍历,直到数组的最后,或者是
        //  达到了能到达的最大下标(此时必定没有超过数组的最大下标)
        for (i = 0; i < asize&&i <= reach; i++) {
            //  从下标i能跳到的最远下标是i + nums[i]
            //  如果这个下标大于reach,那么更新reach
            if (i + nums[i] > reach) {
                reach = i + nums[i];
            }
        }
        //  如果i是到达最大下标才退出的循环,那么返回true,否则false
        return i == asize;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值