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那个差不多,只是思路更隐蔽。

  • 相关阅读:
    关于yyyy-MM-dd格式日期字符串,解析成LocalDateTime遇到的问题
    idea设置代码提示不区分大小写
    不错的Django技术网址
    Django-Rest-Framework 教程: 快速入门
    Djanto static静态文件配置
    Html5 touch event
    Zepto.js touch模块深入分析
    Python单元测试框架之pytest -- fixtures
    Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)
    Nginx基本配置、性能优化指南
  • 原文地址:https://www.cnblogs.com/obama/p/3286128.html
Copyright © 2011-2022 走看看