zoukankan      html  css  js  c++  java
  • leetcode–jump game II

    1.题目描述

    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.
     
    Your goal is to reach the last index in the minimum number of jumps.
     
    For example:
    Given array A = [2,3,1,1,4]
     
    The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

    2.解法分析

    首先判断能不能到达最后一个元素。如果能,接着分析。这里有一个动态规划的解法,不过比较耗时,思路是这样的,设置一个数组dp,dp长度与源数组长度一致,为n.其中dp[i]表示到达数组第i个元素的最短步数,那么dp[i]只跟i之前一步能够到达i的位置有关。于是有了下面的代码,小数据集直接就AC了,大数据集却卡住了,极端情况下这个算法的复杂度是O(N2),但是侥幸心理让我还是写了这个解法,但是还是没过,悲催,先记录一下吧。

    class Solution {
    public:
        int jump(int A[], int n) {
            // Start typing your C/C++ solution below
            // DO NOT write int main() function
            if(n<2)return 0;
            set<int>onestep;
            vector<int> dp;
            dp.assign(n,0);
            
            set<int>::iterator iter;
            for(int i=1;i<n;++i)
            {
                for(iter=onestep.begin();iter!=onestep.end();++iter)
                {
                    if((A[*iter]+*iter)<i)onestep.erase(*iter);
                }
                
                if((i-1+A[i-1])>=i)onestep.insert(i-1);
                
                int minStep=n;
                for(iter=onestep.begin();iter!=onestep.end();++iter)
                {
                    if(dp[*iter]<minStep)
                    {
                        minStep=dp[*iter];
                    }
                }
                
                dp[i]=minStep+1;
            }
            
            return dp[n-1];
            
        }
    };

    然后在网上发现了这么个解法,感觉豁然开朗,我一开始就被动态规划迷住了双眼,这个解法反其道而行之,很妙,思路是这样的,假设我们现在已经知道了再ret步之内能够到达的最远距离last,那么从当前位置到last,我们逐一计算它们一步之内能到达的位置,如果该位置大于last,且大于curr,那么ret+1步之内能到达的最远位置更新为这个值,继续保存在curr之中,一旦我们遍历过了last,那么说明我们需要ret+1步才能到达了,将last设置为curr.重复刚才的判断直至结束。具体的算法很简单,如下:

    /*
     * We use "last" to keep track of the maximum distance that has been reached
     * by using the minimum steps "ret", whereas "curr" is the maximum distance
     * that can be reached by using "ret+1" steps. Thus,
     * curr = max(i+A[i]) where 0 <= i <= last.
     */
    class Solution {
    public:
        int jump(int A[], int n) {
            int ret = 0;
            int last = 0;
            int curr = 0;
            for (int i = 0; i < n; ++i) {
                if (i > last) {
                    last = curr;
                    ++ret;
                }
                curr = max(curr, i+A[i]);
            }
     
            return ret;
        }
    };

    总结,第一反应的算法不是好算法,要仔细想想,其实这个思路跟jump game那个差不多,只是思路更隐蔽。

  • 相关阅读:
    调试代码 2017-03-13
    form表单中的encType属性
    8-2、preparedStatement(预编译声明)、时间类型、大数据(保存MP3等)、批处理(针对增删改,没有查)
    子类能否重写父类的静态方法
    多态部分:Java静态绑定与动态绑定
    DBUtils使用详细示例(参考)
    平时比较常用的Exception解决方法:(随机更新)
    8-1、JDBC对象介绍(4大参数等)
    8、JDBC入门整理
    7、Java之MySQL
  • 原文地址:https://www.cnblogs.com/obama/p/3286128.html
Copyright © 2011-2022 走看看